Gaurab Paul

Polyglot software developer & consultant passionate about web development, distributed systems and open source technologies

Support my blog and open-source work

Tags

Unwrapping composite types in Typescript
Posted  6 years ago

One of the interesting aspects in Typescript is that it is easy to extract out individual types from composite types.

In case of Array, Tuple and Object types, this is really simple, as the type extraction syntax mimic member access syntax.

The object access syntax works for interfaces too, which is quite intuitive:

However, more interesting is that, we can extract types from generics and functions too.

Let us say we have the following Dictionary type

To extract T from StrDict, we can use the above member property approach:

However, another alternative here is to use typescript’s infer keyword along with conditional types:

The conditional type introduced in Typescript 2.8 allows us to arrive at different types based on some conditions. The condition here being a type compatibility constraint.

Not that even though extends keyword is used, this does not necessarily enforce an inheritance relationship, but rather checks for structural compatibility.

infer introduces a type variable here, which can be later collected in the type the conditional type resolves to.

This can be used to collect types from arbitrary generic types using typescript’s inference algorithm.

The same appraoch can be used to extract types from functions too. For example, following type (borrowed from typescript’s collection of built in types), allows us to extract the return value of function.

The analogous approach can be used for arguments too:

Things get somewhat more interesting, if we want to extract the tuple type of all the arguments.

Typescript 3.0-rc introduces support for extracting and spreading parameter lists with tuples. So using typescript@next we can do something like:

It may be tempting to do something like:

This will not work as expected, because U now has to satisfy the type at every position.