【问题标题】:TypeScript type inference in conditional types条件类型中的 TypeScript 类型推断
【发布时间】:2018-10-20 03:27:55
【问题描述】:

我对以下示例中的类型推断方式感到困惑

type RetType<T> = T extends (...args: (infer I)[]) => infer R ? [I, R] : any;
type X = (a: number, b: string) => void;
type Q = RetType<X>;

如果您将鼠标悬停在操场上的 Q 类型上,您将获得 [number &amp; string, void]。这很令人困惑,因为我希望I 被推断为number | string(联合)而不是number &amp; string(交集)。

有人理解为什么输入参数被推断为交集而不是联合吗?

【问题讨论】:

    标签: typescript types type-inference


    【解决方案1】:

    这可能不是您要寻找的答案或解释,但在docs 中提到了这一点:

    同样,同一类型变量在逆变位置的多个候选会导致推断出交集类型:

    type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
    type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>;  // string
    type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>;  // string & number

    【讨论】:

      【解决方案2】:

      TL;DR: 因为无论I 是什么,它都必须可分配给所有函数类型T 的参数。


      这是因为函数参数是反变体。这只是意味着要使用一个函数代替另一个函数,它的参数类型必须与另一个函数相同或更通用。看一个例子就很明显了:

      type f: (arg: string) => string;
      type g: (arg: "foo") => string;
      
      // f is assignable to g, since a function expecting
      // to receive any string should have no problem accepting
      // the specific string "foo".
      
      // However, the reverse isn't true. You can't assign g to f,
      // since g expects to receive exactly the string "foo" for its
      // argument, but if it's used in place of f, it can receive any string.
      

      换句话说,f 可以分配给g,因为g 的参数可以分配给f。这种逆转是相反部分。

      因此,如果T 是某个神秘函数类型(...args: I[]) =&gt; R 的子类型,则自变量逆变告诉我们I 必须可分配给T 的自变量类型。

      因此,T extends (...args: (infer I)[]) =&gt; infer R 告诉 typescript 推断出某个单一类型 I 以便可以使用 I 代替 Tany 参数。

      因此,对于您的类型X,无论I 是什么,它都必须可以分配给两个参数。由于参数类型分别是numberstring,我们问:什么类型可以分配给这两个?

      好吧,number &amp; string


      *更多信息,您可能有兴趣阅读co and contra-variance

      【讨论】:

      • 这是有道理的。一输入问题,我就记得函数参数是逆变的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 2019-09-17
      • 2018-07-03
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      • 2020-10-14
      相关资源
      最近更新 更多