我想做这样的事情:
interface StateItem<T extends StateItemType>{
id: string;
values: {
[key in keyof T]: Provider<corresponding typeof T>
}
}
type Primitive = number | string | Position;
interface StateItemType {
[key: string] : Primitive;
}
interface Mover extends StateItemType {
center: Position;
speed: number;
vector: Position;
accruedVector: Position;
}
const mover : StateItem<Mover> = {
id: "123",
values: {
center: createRandomPosition(),
speed: createRandomNumber(),
vector: createRandomPosition(),
accruedVector: createRandomPosition(),
}
}
也就是说,给定一个简单的key:type映射的接口T
,当我创建一个StateItem<T>
的实例时,必须有一个values
对象,其中包含所有这些对象键和Provider<type>
实例。
我该怎么做?
答案 0 :(得分:2)
您可以使用以下类型来访问T
中每个键的属性值类型:
interface StateItem<T extends StateItemType>{
id: string;
values: {
[key in keyof T]: Provider<T[key]>>
}
}
构造{[key in keyof T]: Provider<T[key]>}
被称为mapped type。它创建一个新类型,其中T
中的每个键都映射到一个新的属性值类型。
key
是一个类型变量,它指向当前使用的键,类似于for...in
循环,您可以在其中使用索引变量连续访问每个属性。 key
也可以在映射类型的属性值类型声明部分中使用。顺便说一句:您可以根据自己的喜好重命名key
,通常使用诸如P
或K
之类的简称来区分那些索引类型变量与实际类型。
在映射类型内,T[key]
将lookup key
内T
变量所保存的当前访问的属性键的属性值类型(要映射的类型) 。因此,类似这样的事情实际上是一个NOOP:
type T1 = { foo: string; bar: number }
type T2 = {[K in keyof T1]: T1[K]} // not very interesting type...
希望,这使事情变得更加清晰!