Skip to content

Instantly share code, notes, and snippets.

@smolijar
Created November 9, 2018 11:59
Show Gist options
  • Save smolijar/5e456b4e1cb8990ade110bf8ecc8f87b to your computer and use it in GitHub Desktop.
Save smolijar/5e456b4e1cb8990ade110bf8ecc8f87b to your computer and use it in GitHub Desktop.

❓ Finding return type for pipe

function pipe<D1, D2, D3, D4, D5, DRes, R1>(
    df: DeltaFn<D1, D2, D3, D4, D5, DRes>,
    r1: RiverFn<DRes, R1>
): ...?;

🤔 If we could just replace return type of a function type...

function pipe<D1, D2, D3, D4, D5, DRes, R1>(
    df: DeltaFn<D1, D2, D3, D4, D5, DRes>,
    r1: RiverFn<DRes, R1>
): ReplaceReturnType<DeltaFn<D1, D2, D3, D4, D5, DRes>, R1>;

✨ Lets assume we can

type ReplaceReturnType<T, R> = (...a: ArgumentTypes<T>) => R;

🔧 And here's how: using infer

type ArgumentTypes<T> = T extends (...args: infer U) => infer R ? U : never;

Inferring respects even type tags such as ? optional etc.

📖 Official docs

type Unpacked<T> =
    T extends (infer U)[] ? U :
    T extends (...args: any[]) => infer U ? U :
    T extends Promise<infer U> ? U :
    T;

type T0 = Unpacked<string>;  // string
type T1 = Unpacked<string[]>;  // string
type T2 = Unpacked<() => string>;  // string
type T3 = Unpacked<Promise<string>>;  // string
type T4 = Unpacked<Promise<string>[]>;  // Promise<string>
type T5 = Unpacked<Unpacked<Promise<string>[]>>;  // string

See Type inference in conditional types 💡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment