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
Copy file name to clipboardExpand all lines: ADVANCED.md
+27-103
Original file line number
Diff line number
Diff line change
@@ -161,113 +161,47 @@ export interface Props {
161
161
[Something to add? File an issue](https://github.com/sw-yx/react-typescript-cheatsheet/issues/new).
162
162
163
163
164
-
## Types for Conditional Rendering
165
-
166
-
Components can render different things based on props that are passed in, and this can be confusing to model in terms of argument and return types. See the Type checks, guards, and assertion strategies discussed above as a first resort.
167
-
168
-
You can also do fairly advanced logic within your types ([they are Turing complete!](https://github.com/Microsoft/TypeScript/issues/14833)). Read the [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html) section of the docs for ideas on how to use `Pick`, `ReadOnly`, `Partial`, and `Record`. Here is an example solution, see the further discussion for other solutions. *thanks to [@jpavon](https://github.com/sw-yx/react-typescript-cheatsheet/issues/12#issuecomment-394440577)*
164
+
## Typing a Component that Accepts Different Props
169
165
166
+
Components, and JSX in general, are analogous to functions. When a component can render differently based on their props, it's similar to how a function can be overloaded to have multiple call signatures. In the same way, you can overload a function component's call signature to list all of its different "versions".
170
167
168
+
A very common use case for this is to render something as either a button or an anchor, based on if it receives a `href` attribute.
function Clickable(props:ButtonProps|AnchorProps) {
181
+
if (isPropsForAnchorElement(props)) {
182
+
return <a{...props} />
183
+
} else {
184
+
return <button{...props} />
185
+
}
186
+
}
192
187
```
193
188
194
-
If you want to conditionaly render a component, sometimes is better to use [React's composition model](https://reactjs.org/docs/composition-vs-inheritance.html) to have simpler components and better to understand typings:
195
-
189
+
They don't even need to be completely different props, as long as they have at least one difference in properties:
Sometimes when intersecting types, we want to define our own version of an attribute. For example, I want my component to have a `label`, but the type I am intersecting with also has a `label` attribute. Here's how to extract that out:
@@ -317,20 +251,10 @@ The advantage of extracting the prop types is that you won't need to export ever
317
251
318
252
319
253
```ts
320
-
// helper type for all known valid JSX element constructors (class and function based)
321
-
typeElementConstructor<P> =
322
-
| ((props:P) =>React.ReactElement<any> |null)
323
-
| (new (props:P) =>React.Component<P, any, any>);
324
-
325
-
// gets the internal props of a component
326
-
// used like Props<typeof MyComponent>
327
-
// or Props<'button'> for intrinsic HTML attributes
0 commit comments