So in part 1 of this series, we looked at how the typeof
operator can be used to infer the Typescript type of an object. There’s a bunch more ways to infer types, and it makes working with Typescript pretty interesting as you can make the type inference do the work for you. Here’s a few of them:
Infer the ReturnType of a function
Works like you’d expect:
1 2 3 4 5 6 7 8 9 10 11 | > function isEmpty(s: string | null | undefined) { return s === "" || s === null || s === undefined } > let a: ReturnType< typeof isEmpty> > a = "hello" [eval].ts:3:1 - error TS2322: Type '"hello"' is not assignable to type 'boolean' . 3 a = "hello" ~ undef |
Note the slightly weird construction: ReturnType <typeof isEmpty>
. That’s because ReturnType (just like all Typescript types) expects a type as a parameter, and not a value.
Infer the type of an instance from the Class Name
Just like ReturnType
, there’s also InstanceType
:
1 2 3 4 | > class Trigger { x = 0; y = 0 } > let g: InstanceType<typeof Trigger> = "hello" [eval].ts:14:5 - error TS2322: Type '"hello"' is not assignable to type 'Trigger'. |
Infer the type of Props of a React Component
Here’s a code fragment from Reactist test suite that illustrates this:
1 2 3 4 5 6 7 8 9 10 11 | const getAvatar = ( props?: Omit<React.ComponentProps< typeof Avatar>, 'user' > & { user?: { name?: string; email: string } } ) => ( <Avatar user={{ name: 'Henning Mus' , email: 'henning@doist.com' }} size= "xl" {...props} /> ) |
As you can see React.ComponentProps
works pretty much like ReturnType
, so you don’t really need to export Props from a component ever. (h/t Janusz)
Typescript has far more complex inference (the infer keyword comes to mind), but this is good enough to start and really simplifies a lot of use-cases, and avoids unneeded type exports from a library.
Leave a Reply to Advanced Typescript: Narrowing & Predicates – Furious BlackbirdCancel reply