Search code examples
typescriptbooleanconditional-types

(Typescript) Generic parameter doesn't compile correctly for conditional type when boolean is used


I have the following type - when P is defined, the function should accept a parameter of type P and return value of type P. Otherwise, it should not take any parameters and 'return' void. For some reason it doesn't work for boolean and:

  1. I don't understand why.
  2. Is there any way to make it work for boolean without explicitly adding additional condition when P extends boolean (as that works).
export type Test<P = void> = P extends void
    ? () => void
    : (payload: P) => P

const test0: Test = () => {} // compiles

const test1: Test<number> = (payload: number): number => payload // compiles

const test2: Test<boolean> = (payload: boolean): boolean => payload // doesn't compile

Solution

  • First why:

    boolean is distributed as union of true | false, so resulting type is
    ((payload: false) => false) | ((payload: true) => true)'.

    More info here


    How to make it work:

    Only "naked types" are candidates for distribution. One of the possible ways to opt out:

    type Test<P = void> = [P] extends [void] 
        ? () => void 
        : (payload: P) => P
    

    Playground