Typescript type T or function () => T usage

You can write:

type Initializer<T> = T extends any ? (T | (() => T)) : never

function correct<T>(arg: Initializer<T>): T {
    return typeof arg === 'function' ? arg() : arg // works
    // arg is Initializer<T> & Function in the true branch
}

const r1 = correct(2) // const r1: 2
const r2 = correct(() => 2) // const r2: number

In the original version, arg is resolved to (() => T) | (T & Function) in the true branch. TS apparently can’t recognize for this union function type, that both constituents are callable. At least in above version, it is clear for the compiler that you can invoke arg after a function check.

Might also be worth to create a github issue for this case in the TypeScript repository – in my opinion T & Function should represent some (wide) type of function.

Leave a Comment