TypeScript Lookup Types: type-safe properties

Typescript 2.1 introduced lookup types. What are they for? In which cases are they useful?

Wait, a video explaining Lookup Types? Yes! Check it out on Egghead.io!

That’s something I was wondering for a while. I read the official docs and Marius Schulz post where quite well explain it, but didn’t totally get the use of it. I needed to come across a real world case where I had to use it.

Then I made a PR to Jest on DefinitelyTyped repository for adding the spyOn function introduced in Jest 19. That’s when I finally understood it.

What exactly are Lookup types?

Basically a lookup type defines an indexed property type of another type. They are created using the keyof operator, which returns an union of string literals:

interface Bike { model: string, weight: number ride: Function } type BikePropNames = keyof Bike type BikePropTypes = Bike[BikePropNames]

Typescript infers the string literals by looking up on the types used, either for the keyof operator and element access.

OK… But when can this be useful?

Let’s take the jest.spyOn function, as an example. The function works takes an object as a first parameter, and the method you wanna spy on as a second parameter. I’ve first wrote it like this:

function spyOn(object: any, method: string)

Yes, this would work. But what if, given the Bike example, I use a non-existent method as a second parameter?

const bike: Bike = { model: 'Orbea X5', weigth: 10, ride: () => console.log('riding!!') } spyOn(bike, 'blabla')

This is not type-safe, ts will not complain at all. How can we do this type-safe?

function spyOn<O, M extends keyof O>(object: O, method: M) ... spyOn(bike, 'blabla') spyOn(bike, 'ride')

If you still don’t understand the spyOn declaration, basically is saying:

  • <O, M extends keyof O>: O is any object, and M is a property of O
  • object: O, method: M: we expect O (any object) as a first parameter, and M (a property of O as a second)

Do you see now the power of lookup types? You can dynamically generate string literal union types! That’ll make your type definitions much more accurate ;)

If you like it, please go and share it! You can follow me on this blog or on twitter as @alexjoverm. Any questions? Shoot!


Originally published at alexjoverm.github.io on April 11, 2017.