【问题标题】:Why isn't the type argument inferred as a union type?为什么类型参数不被推断为联合类型?
【发布时间】:2023-03-15 13:14:01
【问题描述】:

这段代码

declare function fn<T, U>(array: T[], predicates: ((arg: T) => U)[]): [T, U];
let a = fn([1, 2, 3], [x => 2, x => 's']);

导致此错误:

类型参数“U”的类型参数不能从 用法。考虑明确指定类型参数。类型 参数候选“数字”不是有效的类型参数,因为它是 不是候选“字符串”的超类型。函数 fn(数组:T[], 谓词:((arg: T) => U)[]): [T, U]

为什么不能简单地将U 推断为这里有string | number 类型?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    TypeScript 通常不会在泛型推理期间合成联合类型。简单来说,原因是不希望进行这样的推理:

    function compare<T>(x: T, y: T): number { ... }
    // Could infer T: string | number here... but that'd be bad
    compare('oops', 42);
    

    如果不能通过选择一个推理候选来形成泛型类型,您将收到您发布的错误。

    经验决定了这个选择。在以前的版本中(在联合类型存在之前),如果没有推理候选者是所有候选者的超类型,则将推断 {}。在实践中,这会导致 很多 类似于上面示例的错误。

    【讨论】:

    • 有道理。但另一方面,如果我们将predicates 设为U[],则U 推断为联合类型。
    • 为什么U[]((arg: T) =&gt; U)[] 的处理方式不同?
    • U[] 最终成为单个推理候选者,其类型取自数组的元素类型。过去在大致相同的逻辑下不允许使用异构数组,但现在允许使用,因为联合类型通常可以很好地与它们配合使用。
    • ((arg: T) =&gt; U)[] 也是一种异构数组,不是吗?对我来说,它看起来更类似于 U[] 案例,而不是您最初回答中的 compare 函数
    猜你喜欢
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多