Unwrap a Promise in TypeScript

To reference or use a type that's defined in a Promise, the Promise must first be unwrapped.

The utility type that we need is Awaited. It takes a generic T.

Here it is in action. This all type-checks:

type A = string

type B = Promise<A>

type C = Awaited<B>

// typeof b is Promise<string>
const b: B = Promise.resolve('a string')

// typeof c is string
const c: C = 'another string'

// typeof d is string
const d: Awaited<typeof b> = await b

// typeof e is string
const e: Awaited<ReturnType<typeof formatE>> = await formatE()

async function formatE() {
    return 'stringiness'

export {} // module, enabling top-level await