Black lives matter
Portrait Dr. Axel Rauschmayer
Dr. Axel Rauschmayer
Homepage | Twitter
Cover of book “JavaScript for impatient programmers”
Book, exercises, quizzes
(free to read online)
Cover of book “Deep JavaScript”
Book (50% free online)
Cover of book “Tackling TypeScript”
Book (first part free online)
Logo of newsletter “ES.next news”
Newsletter (free)

TypeScript: checking at compile time if an Array lists all property keys

[2022-07-27] dev, typescript
(Ad, please don’t block)

The problem  

Consider the following TypeScript code:

interface Person {
  first: string;
  last: string;
}

const personKeys = [
  'first',
  'last',
] as const;

personKeys lists the property keys of Person. Can we check at compile time if this list is correct?

The solution  

import {assert as tsafeAssert, Equals} from 'tsafe';
tsafeAssert<Equals<
  keyof Person,
  (typeof personKeys)[number]
>>();

Library tsafe enables us to check if two types are equal.

The arguments of Equals<> are computed as follows:

// %inferred-type: "first" | "last"
type A = keyof Person;

// %inferred-type: readonly ["first", "last"]
type B = typeof personKeys;

// %inferred-type: "first" | "last"
type C = B[number];

To compute type C, we are using the indexed access operator T[K]: For a given type T, it computes the types of all properties whose keys are assignable to type K. The following two types are roughly equivalent. That explains the result of computing B[number].

type T = ["first", "last"];
type U = {
  0: "first",
  1: "last",
};

Further reading