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
+55-16
Original file line number
Diff line number
Diff line change
@@ -180,13 +180,52 @@ export interface Props {
180
180
[Something to add? File an issue](https://github.com/sw-yx/react-typescript-cheatsheet/issues/new).
181
181
182
182
183
-
## Types for Conditional Rendering
183
+
## Typing a Component that Accepts Different Props
184
184
185
-
Componentscan 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.
185
+
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".
186
186
187
-
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)*
187
+
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.
188
+
```tsx
189
+
typeButtonProps=JSX.IntrinsicElements['button']
190
+
typeAnchorProps=JSX.IntrinsicElements['a']
191
+
192
+
// optionally use a custom type guard
193
+
function isPropsForAnchorElement(props:ButtonProps|AnchorProps):propsisAnchorProps {
194
+
return'href'inprops
195
+
}
188
196
197
+
function Clickable(props:ButtonProps):JSX.Element
198
+
function Clickable(props:AnchorProps):JSX.Element
199
+
function Clickable(props:ButtonProps|AnchorProps) {
200
+
if (isPropsForAnchorElement(props)) {
201
+
return <a {...props} />
202
+
} else {
203
+
return <button {...props } />
204
+
}
205
+
}
206
+
```
189
207
208
+
They don't even need to be completely different props, as long as they have at least one difference in properties:
209
+
```tsx
210
+
type Omit<T, KextendskeyofT> = Pick<T, Exclude<keyofT, K>>
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)*
228
+
190
229
```tsx
191
230
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
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:
255
+
256
+
<details>
257
+
<summary><b>Approach:Composition</b></summary>
258
+
259
+
Ifyouwanttoconditionallyrenderacomponent, sometimesisbettertouse [React's composition model](https://reactjs.org/docs/composition-vs-inheritance.html) to have simpler components and better to understand typings:
214
260
215
261
```tsx
216
262
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
0 commit comments