如何推断通用属性类型?

时间:2020-01-09 19:48:20

标签: typescript typescript-generics

我不知道如何根据其所在对象的通用类型来推断通用属性的类型。在下面的示例中,如何说Something.aProp需要与Something的U.obj.prop的类型匹配?

interface Prop {
  a: number;
}
interface FancyProp extends Prop {
  b: number;
}

interface Obj<T extends Prop> {
  prop: T;
}

interface FancyObj extends Obj<FancyProp> {}

interface Parent<T extends Obj<any>> { // <-- the <any> here seems wrong too
  obj: T;
}

interface FancyParent extends Parent<FancyObj> {
  fancy: number;
}

class Something<U extends Parent<any>> {
  aProp: typeof U.obj.prop;
}

Something<Parent>.aProp的类型应该为Prop,而Something<FancyParent>.aProp的类型应该是FancyProp

1 个答案:

答案 0 :(得分:0)

对于您的主要问题,在给定对象类型T和键类型K的情况下查找属性值类型的方法是通过括号语法使用lookup types, a.k.a., indexed access types T[K]。因此,如果要查找类型为"prop"的对象的"obj"键属性的U键属性的类型,则可以将该类型写为{{1} }。

请注意,即使键类型是字符串文字,点语法也不适用于类型。如果U["obj"]["prop"]是类型系统中U.obj.prop的同义词,但最好是unfortunately that syntax would collide with namespaces,因为可以有一个名为U["obj"]["prop"]的命名空间,以及一个名为{{ 1}},其导出类型为U,然后obj将引用该类型。


对于您对prop的评论,当U.obj.prop的类型参数any有一个{{时,使用X extends Y<any>并不是真的错误 3}},但它的类型安全性可能比您能得到的要低一些。如果类型Y<T>generic constraint的方式与T相关,则可以使用通用约束代替Y<T>

例如,这可以将T替换为any,并将Parent<T extends Obj<any>>替换为Parent<T extends Obj<Prop>>


这些更改为您提供了如下代码:

U extends Parent<any>

我还向U extends Parent<Obj<Prop>>添加了一个构造函数,因为covariant并且我想证明当interface Parent<T extends Obj<Prop>> { obj: T; } class Something<U extends Parent<Obj<Prop>>> { aProp: U['obj']['prop']; constructor(u: U) { this.aProp = u.obj.prop; } } Something时可以为aProp赋值。 u.obj.pop

这应该可以按您期望的那样工作:

u

好的,希望能有所帮助;祝你好运!

class properties should be initialized