How to rename mapped types


TL;DR

Rename a key using the as keyword in the squared brackets (Typescript docs).

type OriginalObject = {
  a: string;
  b: number;
  c: boolean;
};

// map the OriginalObject to an object of getter functions
type GetterObject = {
  [K in keyof OriginalObject as `get${Uppercase<K>}`]: () => OriginalObject[K];
};

What are mapped types?

Mapped types do exactly what their name suggests: they map over a type and apply a transformation to each property. The syntax is as follows:

type GetterObject = {
  [K in keyof OriginalObject]: () => OriginalObject[K];
};

Compiled you end up with a type of this shape:

type GetterObject = {
  a: () => string;
  b: () => number;
  c: () => boolean;
};

Now if we were to use this how do we separate a data property from a getter function? They are called the same, so calling a could yield wildly different results depending on which type you’re dealing with.

Renaming mapped types

The solution is to rename the mapped keys. This is available since Typescript 4.1. You can work with the key and object to assign the property’s value type, but you can also rename the key itself using the as keyword followed by a mapping.

Here I’m using a Template Literal Type and the builtin Uppercase type to transfer the keys for example from property to setProperty.

type RenamedGetterObject = {
  [K in keyof OriginalObject as `get${Uppercase<K>}`]: () => OriginalObject[K];
};

The actual shape of this type is now:

type GetterObject = {
  getA: () => string;
  getB: () => number;
  getC: () => boolean;
};