Advanced Typescript: Inference

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:

> 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:

> 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:

    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.

8 responses

  1. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  2. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  3. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  4. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  5. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  6. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  7. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

  8. […] the last part of this series, we talked about how you can infer types in Typescript. In this part, we’ll take a look at a related use-case: making the Typescript compiler happy […]

Leave a Reply

Create a website or blog at WordPress.com