【问题标题】:typescript extended generic is not propagated why?typescript 扩展泛型不传播为什么?
【发布时间】:2019-05-20 12:12:00
【问题描述】:

确实遇到了让我困惑的情况。以下是代码的摘录:

type TInputs<A> = A[] | Iterable<A> | Record<string, A>

type TTest = <A, Src extends TInputs<A>>(src: Src) => (x: A) => A

declare const arr: number[]
declare const t: TTest

t (arr) // infered as const t: <{}, number[]>(src: number[]) => (x: {}) => {}
// expected const t: <number, number[]>(src: number[]) => (x: number) => number

我不明白为什么A 没有保存?在这种情况下,有什么理由推断{}
除了了解如何通过该问题之外?

提前感谢您的任何回答
赛博

【问题讨论】:

    标签: typescript generics typescript-typings


    【解决方案1】:

    TypeScript 编译器不会使用泛型约束作为推理位置。有关它的讨论,请参阅 this similar GitHub question。这意味着虽然t(arr) 导致Src 被推断为number[],但生成的约束number[] extends A[] 不能用于推断A。而且由于没有其他方法可以用来推断A,因此推断失败,“我放弃”空类型{}

    要修复它...您实际上可能不需要两个类型参数。如果您希望A 始终是Src 数组的元素类型,那么您可以通过对Srcnumber-index 属性类型执行lookup 来获取该元素类型,即: Src[number] 代替 A

    type TTest = <Src extends any[]>(src: Src) => (x: Src[number]) => Src[number]
    
    declare const arr: number[]
    declare const t: TTest
    t(arr)  // const t: <number[]>(src: number[]) => (x: number) => number
    

    看起来它对我有用。希望有帮助。祝你好运!


    更新

    鉴于您的新类型,可以使用条件类型和inferSrc 获取A,如下所示:

    type AFromSrc<Src extends TInputs<any>> = Src extends TInputs<infer A> ? A : never;
    type TTest = <Src extends TInputs<any>>(src: Src) => 
      (x: AFromSrc<Src>) => AFromSrc<Src>
    

    只要编译器可以从TInputs&lt;A&gt; 推断出A,这也应该有效。这取决于TInputs&lt;&gt; 对推理算法是否足够透明。您应该检查它是否适合您。如果不是,你可能必须更聪明。

    但如果它确实有效,那么您可能需要使用以下更简单的签名:

    type TTest = <A>(src: TInputs<A>) => (x: A) => A
    

    也就是说,保留A 并从中计算Src。这不涉及条件类型,但确实希望编译器能够从TInputs&lt;A&gt; 类型的值推断A。如果可以,那就太好了。如果没有,您将需要使用第一个签名和自定义AFromSrc,以帮助编译器确定A

    好的,再次祝你好运。

    【讨论】:

    • 非常感谢您的快速回答 - 但一个问题是 Src 并不那么简单:/ 它被定义为:type TInputs&lt;A&gt; = TArrays&lt;A&gt;| Iterable&lt;A&gt; | Record&lt;string, A&gt;type TArrays&lt;A&gt; = A extends number ? A[] | TTypedArray : A[] - 不确定如何使用查找在这种情况下 - 我将编辑问题并为链接 btw thx 很多;)
    • 通过简单地删除Ageneric 解决了这个问题,但随后在TArray 类型上遇到了一个问题,因为我只需要在类型是数字时才允许TypedArray,有什么想法吗?
    • 已更新以查看您问题中的新类型(尽管我不知道 TTypedArray 是什么,所以您的里程可能会有所不同)
    • 是的,刚刚看到您的更新,没想到要使用推断(仍然安静的新 héhé)-TTypedArray 只是一种重新组合所有 js 类型数组的类型;)-但是使用您的 AFromSrc我应该没事^^非常感谢
    • 对于您的第二个解决方案,它不起作用,因为我需要 Src 类型作为 实际返回类型
    猜你喜欢
    • 2023-01-12
    • 2018-04-09
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2011-05-26
    • 2013-09-30
    • 2015-04-01
    相关资源
    最近更新 更多