๐ŸŽ“ A1Learner
๐Ÿ”
0 of 37 lessons completed

TypeScript Building Type Utilities

A type utility is a generic type alias that computes a new type from its input. Building one in small steps, with an assignment proving each step, keeps every stage honest.

Reading one position with an indexed access

The indexed access Pair[0] reads the type stored at position 0. The assignment accepts exactly that type.

type Pair = ['pen', 3];

type First = Pair[0];

const firstLabel: First = 'pen';
console.log(firstLabel);

A first attempt reads only the first member

This attempt builds the union from position 0 alone. The second member is refused, and the refusal is the evidence that the attempt is too narrow.

type FirstTryUnion<T extends readonly unknown[]> = T[0];

type OnlyFirst = FirstTryUnion<['alpha', 'beta']>;
const second: OnlyFirst = 'beta';
console.log(second);

TupleToUnion reads every member with an index of number

Indexing with number reads all positions at once, so the computed type is the union of the member types. Assignments accept a string member and the numeric member.

type TupleToUnion<T extends readonly unknown[]> = T[number];

type Member = TupleToUnion<['alpha', 'beta', 7]>;

const wordMember: Member = 'beta';
const numberMember: Member = 7;
console.log(wordMember);
console.log(numberMember);

Length reads the count from a tuple

A tuple type carries its member count as a literal length type. Length reads that member, and the assignment accepts only the count 4.

type Length<T extends readonly unknown[]> = T['length'];

type StepCount = Length<['read', 'check', 'build', 'ship']>;

const stepCount: StepCount = 4;
console.log(stepCount);

Example

type TupleToUnion<T extends readonly unknown[]> = T[number];

type Length<T extends readonly unknown[]> = T['length'];

type Stages = ['draft', 'review', 'publish'];
type Stage = TupleToUnion<Stages>;
type StageCount = Length<Stages>;

const current: Stage = 'review';
const total: StageCount = 3;
console.log(current);
console.log(total);

Key points

  • An indexed access type reads a member type out of another type, such as the element type at a tuple position.
  • Indexing with number reads the union of every element type in a tuple type.
  • A first attempt that reads only position 0 proves too little, and a refused assignment exposes the gap.
  • Reading the length member of a tuple type gives its literal member count.
  • Each build step is verified by assigning values the computed type must accept.

In this example, TupleToUnion and Length both read from one Stages tuple, and the assignments prove the union holds the stage names while the count holds only the literal 3.

Note

An array type has length number, while a tuple type has a literal length, so Length is stated for tuples.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท TypeScript Playground

Exercise

What does indexing a tuple type with number produce?