Skip to content

Commit 12a6345

Browse files
authored
Merge pull request #42 from OpenSesame/cms/blog/typescript-utility-types/index
Automatically generated. Merged on Netlify CMS.
2 parents 1dfa119 + aaf58ec commit 12a6345

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

content/blog/typescript-utility-types/index.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const languages: LanguageName = {
4141

4242
If I try to add German to this list, the compiler displays a nice error.
4343

44-
![TypeScript compile error.](screen-shot-2022-08-16-at-5.29.58-pm.png "Error")
44+
![TypeScript compilation error](screen-shot-2022-08-16-at-5.29.58-pm.png "TypeScript compilation error")
4545

4646
Another common use case is transforming the values of an object to a different type. Instead of maintaining a type that’s just used for the keys of other types, we can use the `keyof` keyword:
4747

@@ -88,18 +88,61 @@ The opposite of `Partial` is `Required`—it makes all the properties of a type
8888

8989
Sometimes you just need a subset of properties from a given type. Instead of creating a new type with values that are duplicated elsewhere in the codebase, you can use `Pick` and `Omit`.
9090

91-
[Pick](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) takes the given properties from a type. We use Pick to build custom React components that are based on other third-party components in order to simply the interface
91+
[Pick](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) takes the given properties from a type. For example, we use `Pick` to build custom React components that wrap other third-party components in order to simply the interface:
9292

93+
```typescript
94+
import Button, { ButtonProps } from '@mui/material/Button';
95+
96+
type CustomButtonProps = Pick<ButtonProps, 'color'>;
97+
98+
function CustomButton({ color }: CustomButtonProps) {
99+
return (
100+
<Button
101+
color={color}
102+
variant="contained"
103+
...
104+
}
105+
```
106+
107+
This pattern helps enforce consistency since it limits the customization possible with props, but it also provides a simpler dev experience.
93108
109+
[Omit](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) works the opposite way: it filters out properties of a given type. This is useful when you want to use an existing type but overwrite one or more of its properties.
94110
95-
If you need to build a custom React component that's based on another, possibly
111+
For example, maybe you have the concept of a "variant" in your design system and you need to expose it as a prop for a custom button, but the new component library you're adopting already uses "variant." You might try something like this:
112+
113+
```typescript
114+
import Button, { ButtonProps } from '@mui/material/Button';
115+
116+
interface CustomButtonProps extends ButtonProps {
117+
variant: 'success' | 'error';
118+
}
119+
```
96120
97-
React componentustom
121+
This won't compile because the custom `variant` type doesn't satisfy the constraints from `ButtonProps:`
98122
123+
![TypeScript compilation error](screen-shot-2022-09-26-at-12.12.20-pm.png "TypeScript compilation error")
99124
125+
It's valid to narrow the type, i.e. `variant: 'contained'`, but you can't overwrite the properties of other interfaces this way.
100126
101-
`Pick` is for creating a custom component that's based on
127+
The way around this is to use `Omit` to first remove the property from the type and then extend that filtered interface:
128+
129+
```typescript
130+
import Button, { ButtonProps } from '@mui/material/Button';
131+
132+
interface CustomButtonProps extends Omit<ButtonProps, 'variant'> {
133+
variant: 'success' | 'error';
134+
}
135+
```
136+
137+
Both utility types can, of course, be combined and use multiple keys to make them even more expressive:
138+
139+
```typescript
140+
interface CustomButtonProps extends Pick<Omit<ButtonProps, 'variant' | 'size'>, 'color' | 'type'> {
141+
variant: 'success' | 'error';
142+
size: 'tiny' | 'big';
143+
}
144+
```
102145
103146
## And Many More
104147
105-
There are a ton of other types. Try them out in the [TypeScript Playground](https://www.typescriptlang.org/play?strictNullChecks=true&q=171#example/built-in-utility-types).
148+
Utility types can save you a lot of time and reduce complexity in your codebase. There are a lot more than what's covered here—you can try them all out in the official [TypeScript Playground](https://www.typescriptlang.org/play?&q=239). These examples just scratch the surface of what you can do with utility types and I hope they can help you improve your TypeScript.
Loading

0 commit comments

Comments
 (0)