Over the past few years of using Typescript and slowly getting comfortable writing complex custom types, I have amassed a collection of small helper types from around the internet. Here are a few of them that I end up adding to almost all my major projects and how I use them:

Unpromise

Sometimes you need to get the resolved value of a Promise<T> wrapped type, mostly when using along with the inbuilt ReturnType type:

type Unpromise<T> = T extends Promise<infer U> ? U : T;

type a = Promise<number>;
type x = Unpromise<a>; // number

Use with ReturnType to make ReturnTypeResolved:

type ReturnTypeResolved<T extends (...args: any) => any> = Unpromise<
  ReturnType<T>
>;

function test(): Promise<{ weird: "value" }> {
  return Promise.resolve({ weird: "value" });
}

type WeirdType = ReturnTypeResolved<typeof test>;

Open in TS Playground

PlainObject

I know we have the inbuilt Record but this is such a common and frequent use case that I like having this around:

type PlainObject<T = any> = Record<string, T>;

type NumMap = PlainObject<number>;
const a: NumMap = {
  key1: 1,
  key2: 2,
  keyx: "x", // ERROR: expected number
};

You can also create a reverse of this, ValueOf<T>:

type ValueOf<T> = T[keyof T];

type x = ValueOf<NumMap>; // number

Open in TS Playground

RecursivePartial

Partial but for nested objects, most useful when declaring defaults or merging some overrides for a config type:

type RecursivePartial<T> = {
  [P in keyof T]?: T[P] extends (infer U)[]
    ? RecursivePartial<U>[]
    : T[P] extends object
    ? RecursivePartial<T[P]>
    : T[P];
};

const config = {
  a: {
    x: {
      p: 1,
      q: 2,
    },
    y: "nested",
    z: "value",
  },
  b: "root",
  c: "value",
};

const configOverride: RecursivePartial<typeof config> = {
  a: {
    x: {
      p: "wrong", // should be number
    },
  },
};

Open in TS Playground

Also See

Go over the inbuilt utility types in the Typescript Docs. And checkout this great library, utility-types on Github for other common types people tend to use.

Credits

Links to the various places I originally found these from: