我想声明一个类型强制的项数组,并能够从中派生联合类型。如果您未为数组中的项目显式指定类型,则此模式有效。我不确定如何最好地解释它,所以这里有一个例子:
示例1
type Pair = {
key: string;
value: number;
};
const pairs: ReadonlyArray<Pair> = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']
示例2
type Data = {
name: string;
age: number;
};
const DataRecord: Record<string, Data> = {
foo: { name: 'Mark', age: 35 },
bar: { name: 'Jeff', age: 56 },
} as const;
type Keys = keyof typeof DataRecord;
这里是使用as const
时导出密钥的示例。我想要相同的行为,但要显式键入数组。
const pairs = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']; // "foo" | "bar"
键的期望值:"foo"|"bar"
键的实际值:string
对于变量,您可以让编译器从初始化中推断类型,也可以明确地将其写出。如果像您一样显式地编写它,则将根据注释检查初始化值,但是初始化器的实际类型不会影响变量的类型(因此会丢失所需的类型信息)。如果让编译器进行推断,就不再可能限制类型以符合特定接口(如您所愿)]
解决方案是使用泛型函数来约束值并推断其实际类型:
type Pair = {
key: string;
value: number;
};
function craetePairsArray<T extends readonly Pair[] & Array<{key: V}>, V extends string>(...args: T) {
return args
}
const pairs = craetePairsArray(
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
)
type Keys1 = typeof pairs[number]['key']
type Data = {
name: string;
age: number;
};
function craeteDataObject<T extends Record<string, Data>>(arg: T) {
return arg;
}
const DataRecord = craeteDataObject({
foo: { name: 'Mark', age: 35 },
bar: { name: 'Jeff', age: 56 },
})
type Keys2 = keyof typeof DataRecord;
注意:对于数组的情况,我们需要让编译器更有力地为key
推断字符串文字类型,从而推断整个& Array<{key: V}>
,其中V
是扩展string
的类型参数>
通常的方法是: