在条件类型上通过泛型传递联合会分配任何值,而不是联合

时间:2019-04-28 14:21:01

标签: typescript

我需要一个通用类型来分配给我的动作。动作可以是函数,也可以是返回函数的函数,例如:

() => void
() => (input: I) => void

我用条件通用输入创建了一个Action类型,如下所示:

type ConditionalInput<I = null> = I extends null
    ? () => void
    : () => (input: I) => void;

当您不通过输入时,效果很好:

const action1: ConditionalInput = () => { } // Fine;

当您传递的输入不是联合时:

const action2: ConditionalInput<string> = () => str => { } // Fine;

但是当您通过并集时输入为any

const action3: ConditionalInput<string | number> =
    () => strOrNum => { } // str is any!!;

这是一个代码为TS Playground

的游乐场

顺便说一句,如果我不使用条件句,则联合会正常工作

type NonConditionalInput<I> = () => (input: I) => void;

const action4: NonConditionalInput<string | number> =
    () => strOrNum => { } // Fine;

1 个答案:

答案 0 :(得分:3)

您遇到了条件类型的distributive behavior。基本上,条件类型应用于联合的每个成员,结果是所有应用程序的联合。因此,根据您的情况,ConditionalInput<string | number> == ((input: string) => void) | ((input: number) => void);

要禁用分发,请使用元组:

type ConditionalInput<I = null> = [I] extends [null]
    ? () => void
    : () => (input: I) => void;


const action3: ConditionalInput<string | number> =
    () => strOrNum => { } // ok now