From 0252317e5d1fc45233b9c74ae902410ecc45e30b Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Fri, 28 Oct 2022 01:41:16 +0800 Subject: [PATCH 01/11] fix: readme links --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index aaeefb8d..081220fa 100644 --- a/README.md +++ b/README.md @@ -61,24 +61,24 @@ Cheatsheets for experienced React developers getting started with TypeScript - [VS Code Extensions](#vs-code-extensions) - [React + TypeScript Starter Kits](#react--typescript-starter-kits) - [Video Tutorial](#video-tutorial) -- [Section 2: Getting Started](#section-2--getting-started) +- [Section 2: Getting Started](#section-2-getting-started) - [Function Components](#function-components) - [Hooks](#hooks) - [useState](#usestate) - [useReducer](#usereducer) - [useEffect / useLayoutEffect](#useeffect--uselayouteffect) - [useRef](#useref) - - [Option 1: DOM element ref](#option-1--dom-element-ref) - - [Option 2: Mutable value ref](#option-2--mutable-value-ref) + - [Option 1: DOM element ref](#option-1-dom-element-ref) + - [Option 2: Mutable value ref](#option-2-mutable-value-ref) - [See also](#see-also) - [useImperativeHandle](#useimperativehandle) - [Custom Hooks](#custom-hooks) - - [More Hooks + TypeScript reading:](#more-hooks---typescript-reading-) - - [Example React Hooks + TypeScript Libraries:](#example-react-hooks---typescript-libraries-) + - [More Hooks + TypeScript reading:](#more-hooks--typescript-reading) + - [Example React Hooks + TypeScript Libraries:](#example-react-hooks--typescript-libraries) - [Class Components](#class-components) - [Typing getDerivedStateFromProps](#typing-getderivedstatefromprops) - - [You May Not Need `defaultProps`](#you-may-not-need--defaultprops-) - - [Typing `defaultProps`](#typing--defaultprops-) + - [You May Not Need `defaultProps`](#you-may-not-need-defaultprops-) + - [Typing `defaultProps`](#typing-defaultprops) - [Consuming Props of a Component with defaultProps](#consuming-props-of-a-component-with-defaultprops) - [Problem Statement](#problem-statement) - [Solution](#solution) @@ -86,8 +86,8 @@ Cheatsheets for experienced React developers getting started with TypeScript - [Typing Component Props](#typing-component-props) - [Basic Prop Types Examples](#basic-prop-types-examples) - [Useful React Prop Type Examples](#useful-react-prop-type-examples) - - [Types or Interfaces?](#types-or-interfaces-) - - [TL;DR](#tl-dr) + - [Types or Interfaces?](#types-or-interfaces) + - [TL;DR](#tldr) - [More Advice](#more-advice) - [Useful table for Types vs Interfaces](#useful-table-for-types-vs-interfaces) - [getDerivedStateFromProps](#getderivedstatefromprops) @@ -96,16 +96,16 @@ Cheatsheets for experienced React developers getting started with TypeScript - [Context](#context) - [Basic Example](#basic-example) - [Extended Example](#extended-example) -- [forwardRef/createRef](#forwardref-createref) +- [forwardRef/createRef](#forwardrefcreateref) - [Generic forwardRefs](#generic-forwardrefs) - [Option 1 - Wrapper component](#option-1---wrapper-component) - [Option 2 - Redeclare forwardRef](#option-2---redeclare-forwardref) - [More Info](#more-info) - [Portals](#portals) - [Error Boundaries](#error-boundaries) -- [Option 1: Using react-error-boundary](#option-1--using-react-error-boundary) -- [Options 2: Writing your custom error boundary component](#options-2--writing-your-custom-error-boundary-component) -- [Concurrent React/React Suspense](#concurrent-react-react-suspense) +- [Option 1: Using react-error-boundary](#option-1-using-react-error-boundary) +- [Options 2: Writing your custom error boundary component](#options-2-writing-your-custom-error-boundary-component) +- [Concurrent React/React Suspense](#concurrent-reactreact-suspense) - [Troubleshooting Handbook: Types](#troubleshooting-handbook--types) - [Union Types and Type Guarding](#union-types-and-type-guarding) @@ -127,15 +127,15 @@ Cheatsheets for experienced React developers getting started with TypeScript - [Frequent Known Problems with TypeScript](#frequent-known-problems-with-typescript) - [TypeScript doesn't narrow after an object element null check](#typescript-doesnt-narrow-after-an-object-element-null-check) - [TypeScript doesn't let you restrict the type of children](#typescript-doesnt-let-you-restrict-the-type-of-children) -- [Troubleshooting Handbook: Operators](#troubleshooting-handbook--operators) -- [Troubleshooting Handbook: Utilities](#troubleshooting-handbook--utilities) -- [Troubleshooting Handbook: tsconfig.json](#troubleshooting-handbook--tsconfigjson) -- [Troubleshooting Handbook: Fixing bugs in official typings](#troubleshooting-handbook--fixing-bugs-in-official-typings) -- [Troubleshooting Handbook: Globals, Images and other non-TS files](#troubleshooting-handbook--globals--images-and-other-non-ts-files) +- [Troubleshooting Handbook: Operators](#troubleshooting-handbook-operators) +- [Troubleshooting Handbook: Utilities](#troubleshooting-handbook-utilities) +- [Troubleshooting Handbook: tsconfig.json](#troubleshooting-handbook-tsconfigjson) +- [Troubleshooting Handbook: Fixing bugs in official typings](#troubleshooting-handbook-fixing-bugs-in-official-typings) +- [Troubleshooting Handbook: Globals, Images and other non-TS files](#troubleshooting-handbook-globals-images-and-other-non-ts-files) - [Editor Tooling and Integration](#editor-tooling-and-integration) - [Linting](#linting) -- [Other React + TypeScript resources](#other-react---typescript-resources) -- [Recommended React + TypeScript talks](#recommended-react---typescript-talks) +- [Other React + TypeScript resources](#other-react--typescript-resources) +- [Recommended React + TypeScript talks](#recommended-react--typescript-talks) - [Time to Really Learn TypeScript](#time-to-really-learn-typescript) - [Example App](#example-app) From ad81747f570ea2c13308a442667d952bdfa144c8 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Fri, 28 Oct 2022 01:45:43 +0800 Subject: [PATCH 02/11] fix: links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 081220fa..1321cf71 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Cheatsheets for experienced React developers getting started with TypeScript - [Example React Hooks + TypeScript Libraries:](#example-react-hooks--typescript-libraries) - [Class Components](#class-components) - [Typing getDerivedStateFromProps](#typing-getderivedstatefromprops) - - [You May Not Need `defaultProps`](#you-may-not-need-defaultprops-) + - [You May Not Need `defaultProps`](#you-may-not-need-defaultprops) - [Typing `defaultProps`](#typing-defaultprops) - [Consuming Props of a Component with defaultProps](#consuming-props-of-a-component-with-defaultprops) - [Problem Statement](#problem-statement) @@ -106,7 +106,7 @@ Cheatsheets for experienced React developers getting started with TypeScript - [Option 1: Using react-error-boundary](#option-1-using-react-error-boundary) - [Options 2: Writing your custom error boundary component](#options-2-writing-your-custom-error-boundary-component) - [Concurrent React/React Suspense](#concurrent-reactreact-suspense) -- [Troubleshooting Handbook: Types](#troubleshooting-handbook--types) +- [Troubleshooting Handbook: Types](#troubleshooting-handbook-types) - [Union Types and Type Guarding](#union-types-and-type-guarding) - [Optional Types](#optional-types) From 4bdda012763b31b8bce9b42e2079c22d6677bf72 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Mon, 31 Oct 2022 00:21:54 +0800 Subject: [PATCH 03/11] useCallback implicit any docs --- docs/basic/getting-started/hooks.md | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 883815c1..2ca03385 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -37,6 +37,48 @@ setUser(newUser); This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. You should follow up by setting the `user` state — if you don't, the rest of your code may rely on the fact that `user` is of type `User` and that may lead to runtime errors. +## useCallback + +You can type the `useCallback` just like any other functions + +```ts +const memoizedCallback = useCallback( + (param1: string, param2: number) => { + console.log(param1, param2) + return { ok: true } + }, + [...], +); +/** + * VSCode will show the following type: + * const memoizedCallback: + * (param1: string, param2: number) => { ok: boolean } + */ +``` + +Note that for React < 18, the function signiture of `useCallback` is as follow, in which the args are typed as `any[]` as default. + +```ts +function useCallback any>( + callback: T, + deps: DependencyList +): T; +``` + +In React >= 18, the function signiture of `useCallback` changed to the following, + +```ts +function useCallback(callback: T, deps: DependencyList): T; +``` + +Therefore the follow code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. + +```ts +useCallback((e) => {}, []); +``` + +See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210 + ## useReducer You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it. From 93dd6ee971f15b516f9560d0b275b85b8c887a3d Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Mon, 31 Oct 2022 00:25:40 +0800 Subject: [PATCH 04/11] update readme.md --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index 1321cf71..f357b31e 100644 --- a/README.md +++ b/README.md @@ -387,6 +387,48 @@ setUser(newUser); This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. You should follow up by setting the `user` state — if you don't, the rest of your code may rely on the fact that `user` is of type `User` and that may lead to runtime errors. +#### useCallback + +You can type the `useCallback` just like any other functions + +```ts +const memoizedCallback = useCallback( + (param1: string, param2: number) => { + console.log(param1, param2) + return { ok: true } + }, + [...], +); +/** + * VSCode will show the following type: + * const memoizedCallback: + * (param1: string, param2: number) => { ok: boolean } + */ +``` + +Note that for React < 18, the function signiture of `useCallback` is as follow, in which the args are typed as `any[]` as default. + +```ts +function useCallback any>( + callback: T, + deps: DependencyList +): T; +``` + +In React >= 18, the function signiture of `useCallback` changed to the following, + +```ts +function useCallback(callback: T, deps: DependencyList): T; +``` + +Therefore the follow code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. + +```ts +useCallback((e) => {}, []); +``` + +See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210 + #### useReducer You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it. From 407d629cd7b2d468242db2caea276373c789d95b Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 31 Oct 2022 10:17:51 +0100 Subject: [PATCH 05/11] Apply suggestions from code review --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f357b31e..7d50fbf6 100644 --- a/README.md +++ b/README.md @@ -406,7 +406,7 @@ const memoizedCallback = useCallback( */ ``` -Note that for React < 18, the function signiture of `useCallback` is as follow, in which the args are typed as `any[]` as default. +Note that for React < 18, the function signature of `useCallback` typed arguments as any[]` by default: ```ts function useCallback any>( @@ -415,20 +415,21 @@ function useCallback any>( ): T; ``` -In React >= 18, the function signiture of `useCallback` changed to the following, +In React >= 18, the function signature of `useCallback` changed to the following: ```ts function useCallback(callback: T, deps: DependencyList): T; ``` -Therefore the follow code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. +Thereforee the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. ```ts +// @ts-expect-error Parameter 'e' implicitly has 'any' type. useCallback((e) => {}, []); +// Explicit 'any' type. +useCallback((e: any) => {}, []); ``` -See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210 - #### useReducer You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it. From 7ec665a0fe017f011711d9d4376b68f4de516cc2 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Mon, 31 Oct 2022 10:19:30 +0100 Subject: [PATCH 06/11] Backport suggestions --- docs/basic/getting-started/hooks.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 2ca03385..39f1a291 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -56,7 +56,7 @@ const memoizedCallback = useCallback( */ ``` -Note that for React < 18, the function signiture of `useCallback` is as follow, in which the args are typed as `any[]` as default. +Note that for React < 18, the function signature of `useCallback` typed arguments as any[]` by default: ```ts function useCallback any>( @@ -65,20 +65,21 @@ function useCallback any>( ): T; ``` -In React >= 18, the function signiture of `useCallback` changed to the following, +In React >= 18, the function signature of `useCallback` changed to the following: ```ts function useCallback(callback: T, deps: DependencyList): T; ``` -Therefore the follow code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. +Thereforee the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. ```ts +// @ts-expect-error Parameter 'e' implicitly has 'any' type. useCallback((e) => {}, []); +// Explicit 'any' type. +useCallback((e: any) => {}, []); ``` -See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210 - ## useReducer You can use [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it. From 93cdf05f8b01ffdcd025abfe5082c7b3c565ba3b Mon Sep 17 00:00:00 2001 From: eps1lon Date: Mon, 31 Oct 2022 10:21:49 +0100 Subject: [PATCH 07/11] More typos --- README.md | 4 ++-- docs/basic/getting-started/hooks.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7d50fbf6..0daeaca5 100644 --- a/README.md +++ b/README.md @@ -389,7 +389,7 @@ This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. #### useCallback -You can type the `useCallback` just like any other functions +You can type the `useCallback` just like any other function. ```ts const memoizedCallback = useCallback( @@ -421,7 +421,7 @@ In React >= 18, the function signature of `useCallback` changed to the following function useCallback(callback: T, deps: DependencyList): T; ``` -Thereforee the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. +Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. ```ts // @ts-expect-error Parameter 'e' implicitly has 'any' type. diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 39f1a291..71c4769a 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -39,7 +39,7 @@ This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. ## useCallback -You can type the `useCallback` just like any other functions +You can type the `useCallback` just like any other function. ```ts const memoizedCallback = useCallback( @@ -71,7 +71,7 @@ In React >= 18, the function signature of `useCallback` changed to the following function useCallback(callback: T, deps: DependencyList): T; ``` -Thereforee the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. +Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. ```ts // @ts-expect-error Parameter 'e' implicitly has 'any' type. From 11ed02f6c87558f7356797e432e5475392351b63 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Mon, 31 Oct 2022 10:22:54 +0100 Subject: [PATCH 08/11] Formatting --- README.md | 2 +- docs/basic/getting-started/hooks.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0daeaca5..e4e5f6af 100644 --- a/README.md +++ b/README.md @@ -406,7 +406,7 @@ const memoizedCallback = useCallback( */ ``` -Note that for React < 18, the function signature of `useCallback` typed arguments as any[]` by default: +Note that for React < 18, the function signature of `useCallback` typed arguments as `any[]` by default: ```ts function useCallback any>( diff --git a/docs/basic/getting-started/hooks.md b/docs/basic/getting-started/hooks.md index 71c4769a..f2091d11 100644 --- a/docs/basic/getting-started/hooks.md +++ b/docs/basic/getting-started/hooks.md @@ -56,7 +56,7 @@ const memoizedCallback = useCallback( */ ``` -Note that for React < 18, the function signature of `useCallback` typed arguments as any[]` by default: +Note that for React < 18, the function signature of `useCallback` typed arguments as `any[]` by default: ```ts function useCallback any>( From 4a9964d456d6d7a8f5dc3fb9b59d15b47cca80cd Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Wed, 2 Nov 2022 09:46:57 +0800 Subject: [PATCH 09/11] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Filip Tammergård <44197016+filiptammergard@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4e5f6af..a0157eac 100644 --- a/README.md +++ b/README.md @@ -389,7 +389,7 @@ This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. #### useCallback -You can type the `useCallback` just like any other function. +You can type `useCallback` just like any other function. ```ts const memoizedCallback = useCallback( From e2eef088d69a0e0b2ce7cdbcd101bc4b38f56ab9 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Wed, 2 Nov 2022 09:47:03 +0800 Subject: [PATCH 10/11] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Filip Tammergård <44197016+filiptammergard@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0157eac..fa18d12e 100644 --- a/README.md +++ b/README.md @@ -421,7 +421,7 @@ In React >= 18, the function signature of `useCallback` changed to the following function useCallback(callback: T, deps: DependencyList): T; ``` -Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. +Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not in React < 18. ```ts // @ts-expect-error Parameter 'e' implicitly has 'any' type. From 4d19e855576eb5650ad073a62c143366fa4716b3 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Wed, 2 Nov 2022 10:18:46 +0800 Subject: [PATCH 11/11] chore: update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa18d12e..e4e5f6af 100644 --- a/README.md +++ b/README.md @@ -389,7 +389,7 @@ This temporarily "lies" to the TypeScript compiler that `{}` is of type `User`. #### useCallback -You can type `useCallback` just like any other function. +You can type the `useCallback` just like any other function. ```ts const memoizedCallback = useCallback( @@ -421,7 +421,7 @@ In React >= 18, the function signature of `useCallback` changed to the following function useCallback(callback: T, deps: DependencyList): T; ``` -Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not in React < 18. +Therefore, the following code will yield "`Parameter 'e' implicitly has an 'any' type.`" error in React >= 18, but not <17. ```ts // @ts-expect-error Parameter 'e' implicitly has 'any' type.