Для вашего основного вопроса, способ поиска типа значения свойства по типу объекта T
и типу ключа K
заключается в использовании типов поиска, или индексированных типов доступа через синтаксис скобки T[K]
. Поэтому, если вы хотите найти тип свойства "prop"
-keyed свойства "obj"
-keyed объекта типа U
, вы должны написать этот тип как U["obj"]["prop"]
.
Обратите внимание, что точечный синтаксис не работает для типов, даже если ключевые типы являются строковыми литералами. Было бы неплохо, если бы U.obj.prop
был синонимом для U["obj"]["prop"]
в системе типов, но, к сожалению, , к сожалению, этот синтаксис столкнулся бы с пространствами имен , поскольку могло бы существовать пространство имен с именем U
, с подпространством именованных obj
с экспортированным типом с именем prop
, а затем U.obj.prop
будет ссылаться на этот тип.
Ваши комментарии о any
не совсем неправильно использовать X extends Y<any>
, когда параметр типа Y<T>
T
имеет generi c ограничение , но оно может быть менее безопасным, чем вы можете получить. Если тип Y<T>
относится к T
ковариантным способом , то вместо any
можно использовать ограничение generi c.
Это означает, например, что Parent<T extends Obj<any>>
можно заменить на Parent<T extends Obj<Prop>>
, а U extends Parent<any>
можно заменить на U extends Parent<Obj<Prop>>
.
Эти изменения дают вам код как это:
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
является U
.
И это должно работать так, как вы ожидаете:
interface PlainObj extends Obj<Prop> { }
interface PlainParent extends Parent<PlainObj> { }
new Something<PlainParent>({ obj: { prop: { a: 1 } } }).aProp.a; // number
interface FancyObj extends Obj<FancyProp> { }
interface FancyParent extends Parent<FancyObj> {
fancy: number;
}
new Something<FancyParent>({ obj: { prop: { a: 1, b: 2 } }, fancy: 3 }).aProp.b; // number
Хорошо, надеюсь, это поможет; удачи!
Детская площадка ссылка на код