【问题标题】:Conditional generic type of function is being broke up into fragments of types函数的条件泛型类型被分解为类型的片段
【发布时间】:2020-03-21 13:43:48
【问题描述】:

我正在尝试编写一个通用条件类型。我的尝试是:

type Some<T> = T extends (...args: any[]) => any ? (p: T) => T : T | ((p: T) => T);

当我创建这种类型的变量时

let v: Some<(() => void) | string | boolean>;

原来的类型是

string | boolean | ((p: string) => string) | ((p: false) => false) | ((p: true) => true) | ((p: () => void) => () => void)

即使 boolean 类型已被分解为 truefalse 类型,它们的行为也各不相同。我实际上想要构建的类型是

string | boolean | ((p: string | boolean | (() => void)) => string | boolean | (() => void))

我该怎么做?

【问题讨论】:

    标签: typescript typescript-generics conditional-types


    【解决方案1】:

    这是因为条件类型是distributive。我不确定是否可以通过这种方式获得您想要的类型。但是,您可以用不同的方式描述类型,例如:

    type Some<T> = Exclude<T, Function> | ((p: T) => T);
    

    至少生成的类型看起来像您期望的类型。 Playground link.

    【讨论】:

    • 请注意,您可以使用内置实用程序类型Exclude&lt;T, U&gt;,而不是定义Diff
    • @jcalz 感谢您的评论!我已经更新了答案
    • 我明白了你的意思。谢谢你。您的解决方案存在缺陷。您对用例 () =&gt; void 进行了硬编码。它非常适用于T = (() =&gt; void) | string | boolean。结果是string | boolean | ((p: string | boolean | (() =&gt; void)) =&gt; string | boolean | (() =&gt; void)) 但对于(() =&gt; number) | string | boolean 是错误的:string | boolean | ((p: string | boolean | (() =&gt; void)) =&gt; string | boolean | (() =&gt; number)) 应该是string | boolean | ((p: string | boolean | (() =&gt; number)) =&gt; string | boolean | (() =&gt; number))
    • 实际的解决方案是降低您的命题的复杂性:Exclude&lt;T, Function&gt; | ((p: T) =&gt; T)
    • @AndreiKovalev 可能是,我只是试图创建一个与问题类型匹配的类型:) 但是如果不了解问题上下文就很难提出正确的解决方案。我也是从你来的类型入手的,但是不匹配,所以稍微复杂了一点:)
    猜你喜欢
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 2021-12-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多