Some cool type tips in TypeScript

Posted on 2023-08-17 in Trucs et astuces

Here is an unsorted type tips I find useful in TypeScript. I may update it when I find new ones. Don't hesitate to share yours in the comments!

Another good start, is to read this page from the handbook which list various builtin utility types. If you are really motivated and want to check your skills, you can try these challenges: I stopped after some intermediate ones, but even the easy ones will help you practice and learn new things (I sure did!).

Misc

  • typeof allows you to get the type of a variable.
  • Exclude<UnionType, ExcludedMembers> is like Omit but for union types.
  • Extract<Type, Union>``constructs a type by extracting from ``Type all union members that are assignable to Union.
  • keyof allows you to build a union type from the keys of an object.
  • extends allows you to put constraints on a type. See examples in the Advanced section.

Advanced

You can use infer to infer types to build more complex ones:

type MyAwaitable<T> = T extends Promise<infer Value> ? Value : never;

// MyValue is a string.
type MyValue = MyAwaitable<Promise<string>>
type First<T extends any[]> = T extends [infer P, ...any[]] ? P : never

const a: [string, number] = ['Hello', 1]
// Value is a string.
type Value = First<typeof a>
type SavedData = {
    options: {isEnabled: boolean};
    authentication: {username: string};
}

const saveData = <Key extends keyof SavedData>(key: Key, data: SavedData[Key]): void => {
    localStorage.setItem(key, JSON.stringify(data));
}

saveData('options', {isEnabled: false})
saveData('authentication', {username: 'Jujens'})
// Those will be reported as errors.
saveData('options', {username: 'Jujens'})
saveData('authentication', {isEnabled: false})

You can define types with string interpolation to force part of a string to be of a certain type:

type Width = `${number}px`

const a: Width = '18px'
// All these will be reported as errors.
const b: Width = 18;
const c: Width = '18';
const d: Width = 'totopx'