You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[_See this in the TS Playground_](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQNwCwAUI4wPQtwCuqyA5lowQ4A7fMAhC4AQTBgAFAEo4Ab0Zw4bOABUAnmCzkARAQgQDZOMHRCI8NKmA8hyAEYAbfTAhwYu-WQPOHDCeQgZwAD5wBqgcziDAMGGRBpSoWIkRnEIAJlgEwEJY2WQAdLIATADM5eXyqurslDAcUBIAPABCQSHevgC8RiYGAHxwqK7ZANYAVnBtLF3B4sP19RrWcFhQxFD1TS3tiz0+egOBS6GjMFgAHvDzR8uMAL7MDBqgYO4gWEIwyDAxEJGLdILALH8tgQ8PpHkIAArEMDoW7XHLobB4GAlADCJEghT+iIgyLaZHOITIoxUDDUqD0uGAyFcxLAAH4AFxjGBQAo8egMV4MUHQQjCUTiOBw2RgJGoLlw1moRQ0tS4cSoeBKMYMpkspEAGjgJRNqXgzzgfTgspJqAFag02S8qBI6QAFny4AB3BJunVYRnM1l7dIHOYUyVKE0lM0WljDAXPIA)
37
+
38
+
<details>
39
+
<summary>
40
+
41
+
Why not `JSX.IntrinsicElements` or `React.[Element]HTMLAttributes` or `React.HTMLProps` or `React.HTMLAttributes`?
42
+
43
+
</summary>
44
+
45
+
### Using `JSX.IntrinsicElements` or `React.[Element]HTMLAttributes`
46
+
47
+
There are at least 2 other equivalent ways to do this:
48
+
49
+
```tsx
50
+
// Method 1: JSX.IntrinsicElements
51
+
typebtnType=JSX.IntrinsicElements["button"]; // cannot inline or will error
Looking at [the source for `ComponentProps`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f3134f4897c8473f590cbcdd5788da8d59796f45/types/react/index.d.ts#L821) shows that this is a clever wrapper for `JSX.IntrinsicElements`, whereas the second method relies on specialized interfaces with unfamiliar naming/capitalization.
59
+
60
+
> Note: There are over 50 of these specialized interfaces available - look for `HTMLAttributes` in our [`@types/react` commentary](https://react-typescript-cheatsheet.netlify.app/docs/advanced/types_react_api#typesreact).
61
+
62
+
Ultimately, [we picked the `ComponentProps` method](https://github.com/typescript-cheatsheets/react/pull/276/files) as it involves the least TS specific jargon and has the most ease of use. But you'll be fine with either of these methods if you prefer.
63
+
64
+
### Definitely not `React.HTMLProps` or `React.HTMLAttributes`
65
+
66
+
This is what happens when you use `React.HTMLProps`:
type:"button"|"submit"|"reset"; // flaw of React.HTMLProps
21
71
}
22
72
exportfunction Button(props:ButtonProps) {
23
73
const { specialProp, ...rest } =props;
24
-
//do something with specialProp
74
+
//ERROR: Type 'string' is not assignable to type '"button" | "submit" | "reset" | undefined'.
25
75
return <button{...rest} />;
26
76
}
27
77
```
28
78
29
-
## Wrapping/Mirroring a Component
79
+
It infers a too-wide type of `string` for `type`, because it [uses `AllHTMLAttributes` under the hood](https://github.com/typescript-cheatsheets/react/issues/128#issuecomment-508103558).
80
+
81
+
This is what happens when you use `React.HTMLAttributes`:
Copy file name to clipboardExpand all lines: docs/advanced/types-react-ap.md
+67-3Lines changed: 67 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -28,15 +28,79 @@ Most Commonly Used Interfaces and Types
28
28
Not Commonly Used but Good to know
29
29
30
30
-`Ref` - used to type `innerRef`
31
-
-`ElementType` - used for higher order components or operations on components
31
+
-`ElementType` - used for higher order components or operations on components, e.g. [Polymorphic Components](https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase#polymorphic-components)
32
32
-`ReactElement` - [can be used if you want to pass it to `cloneElement`](https://www.reddit.com/r/reactjs/comments/ia8sdi/any_other_typescript_users_constantly_confused/g1npahe/) aka it's pretty rarely used
33
33
-`ComponentType` - used for higher order components where you don't specifically deal with the intrinsic components
34
34
-`ReactPortal` - used if you specifically need to type a prop as a portal, otherwise it is part of `ReactNode`
35
35
-`ComponentClass` - a complete interface for the produced constructor function of a class declaration that extends `Component`, often used to type external components instead of typing your own
36
36
-`JSXElementConstructor` - anything that TypeScript considers to be a valid thing that can go into the opening tag of a JSX expression
37
-
-`ComponentProps` - props of a component
37
+
-`ComponentProps` - props of a component - most useful for [Wrapping/Mirroring a HTML Element](https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase#wrappingmirroring-a-html-element)
38
38
-`ComponentPropsWithRef` - props of a component where if it is a class-based component it will replace the `ref` prop with its own instance type
39
39
-`ComponentPropsWithoutRef` - props of a component without its `ref` prop
40
+
-`HTMLProps` and `HTMLAttributes` - these are the most generic versions, for global attributes (see a list of [attributes marked as "global attribute" on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes)). In general, prefer `React.ComponentProps`, `JSX.IntrinsicElements`, or [specialized HTMLAttributes interfaces](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a2aa0406e7bf269eef01292fcb2b24dee89a7d2b/types/react/index.d.ts#L1914-L2625):
41
+
42
+
<details>
43
+
44
+
<summary>
45
+
List of specialized HTMLAttributes
46
+
</summary>
47
+
48
+
Note that there are about 50 of these, which means there are some HTML elements which are not covered.
49
+
50
+
- `AnchorHTMLAttributes`
51
+
- `AudioHTMLAttributes`
52
+
- `AreaHTMLAttributes`
53
+
- `BaseHTMLAttributes`
54
+
- `BlockquoteHTMLAttributes`
55
+
- `ButtonHTMLAttributes`
56
+
- `CanvasHTMLAttributes`
57
+
- `ColHTMLAttributes`
58
+
- `ColgroupHTMLAttributes`
59
+
- `DataHTMLAttributes`
60
+
- `DetailsHTMLAttributes`
61
+
- `DelHTMLAttributes`
62
+
- `DialogHTMLAttributes`
63
+
- `EmbedHTMLAttributes`
64
+
- `FieldsetHTMLAttributes`
65
+
- `FormHTMLAttributes`
66
+
- `HtmlHTMLAttributes`
67
+
- `IframeHTMLAttributes`
68
+
- `ImgHTMLAttributes`
69
+
- `InsHTMLAttributes`
70
+
- `InputHTMLAttributes`
71
+
- `KeygenHTMLAttributes`
72
+
- `LabelHTMLAttributes`
73
+
- `LiHTMLAttributes`
74
+
- `LinkHTMLAttributes`
75
+
- `MapHTMLAttributes`
76
+
- `MenuHTMLAttributes`
77
+
- `MediaHTMLAttributes`
78
+
- `MetaHTMLAttributes`
79
+
- `MeterHTMLAttributes`
80
+
- `QuoteHTMLAttributes`
81
+
- `ObjectHTMLAttributes`
82
+
- `OlHTMLAttributes`
83
+
- `OptgroupHTMLAttributes`
84
+
- `OptionHTMLAttributes`
85
+
- `OutputHTMLAttributes`
86
+
- `ParamHTMLAttributes`
87
+
- `ProgressHTMLAttributes`
88
+
- `SlotHTMLAttributes`
89
+
- `ScriptHTMLAttributes`
90
+
- `SelectHTMLAttributes`
91
+
- `SourceHTMLAttributes`
92
+
- `StyleHTMLAttributes`
93
+
- `TableHTMLAttributes`
94
+
- `TextareaHTMLAttributes`
95
+
- `TdHTMLAttributes`
96
+
- `ThHTMLAttributes`
97
+
- `TimeHTMLAttributes`
98
+
- `TrackHTMLAttributes`
99
+
- `VideoHTMLAttributes`
100
+
- `WebViewHTMLAttributes`
101
+
102
+
</details>
103
+
40
104
- all methods: `createElement`, `cloneElement`, ... are all public and reflect the React runtime API
41
105
42
106
[@Ferdaber's note](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/69): I discourage the use of most `...Element` types because of how black-boxy `JSX.Element` is. You should almost always assume that anything produced by `React.createElement` is the base type `React.ReactElement`.
@@ -45,7 +109,7 @@ Not Commonly Used but Good to know
45
109
46
110
-`Element` - the type of any JSX expression. You should ideally never need to see or use this, but you do because of [a limitation of TypeScript](https://github.com/microsoft/TypeScript/issues/21699).
47
111
-`LibraryManagedAttributes` - It specifies other places where JSX elements can declare and initialize property types. Used to resolve static `defaultProps` and `propTypes` with the internal props type of a component.
48
-
-`IntrinsicElements` - every possible built-in component that can be typed in as a lowercase tag name in JSX
112
+
-`IntrinsicElements` - every possible built-in component that can be typed in as a lowercase tag name in JSX. If you're using this to get the attributes for a HTML element, `React.ComponentProps<element>` may be more readable as it doesn't require knowing what "Intrinsic" means.
0 commit comments