【问题标题】:Extracting types of properties of generic interfaces still requires unnecessary generic type提取泛型接口的属性类型仍然需要不必要的泛型类型
【发布时间】:2020-01-03 19:41:10
【问题描述】:

当我有一个这样的泛型接口时:

   interface I1<S> {
      a: string;
      b: genericType<S>
}

并尝试使用I1['a'] 提取属性a 的类型,打字稿会抛出以下错误:

TS2314: Generic type 'I1&lt;S&gt;' requires 1 type argument(s).

由于提取的属性类型实际上并不依赖于&lt;S&gt;,这不应该吗?要么我无法理解 Typescript 的实际工作原理,要么这确实应该没问题。

Playground Link

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    属性a 类型不依赖于S,但您不能将类型参数作为lookup 的一部分省略。一些选项:

    1.) 将S 设置为unknown

    type T1 = I1<unknown>["a"] // string
    

    2.) 在界面中声明S 的默认值

    interface I2<S = unknown> {
      a: string;
      b: S
    }
    
    type T2 = I2["a"] // string
    

    3.) 保持通用

    type T3<S> = I1<S>["a"]  // T3<S> = string
    // doesn't make too much sense in this particular case
    

    Here is a sample

    【讨论】:

    • 谢谢。因此,如果我理解正确,TS 必须在访问其成员之前实例化接口?
    • type T1 = I1&lt;unknown&gt;["a"] 中,I1&lt;unknown&gt;["a"] 实际上是type reference,其中必须提供所有类型参数才能将其用作实际类型(称为泛型类型的实例化; this 可能对你来说也很有趣)。希望,这会有所帮助。
    【解决方案2】:

    应该是:

    interface I1<S> {
          a: string;
          b: S;
    }
    

    并且在制作对象时需要给出S的类型:

    请注意,我为下面的 S 泛型类型参数提供了字符串类型,但这可以是您希望 "b" 成为的任何类型。

    const i1object: I1<string> = { a: "a", b: "b" };
    const i1object2: I1<number> = { a: "a", b: 5 };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2019-07-21
      • 2016-10-16
      • 1970-01-01
      相关资源
      最近更新 更多