【发布时间】:2021-11-26 13:38:08
【问题描述】:
假设我们有一个类型
type Foo = {
a: string;
b: number;
c: boolean;
}
我现在想为具有给定类型T 的key 和value 的对象定义一个类型,以便直接从键中推断出值的类型,这样我就可以做到:
const kv1: KeyValue<Foo> = {key: 'a', value: 'STRING'};
const kv2: KeyValue<Foo> = {key: 'b', value: 42};
const kv3: KeyValue<Foo> = {key: 'c', value: true};
如果我只是这样做:
type KeyValue<T> = {
key: keyof T;
value: T[keyof T]
}
...那么显然这些值将是Foo 中所有属性值的并集:
如果我这样做:
type KeyValue<T, K extends keyof T> = {
key: K;
value: T[K]
}
... 那么可以肯定,如果明确键入 KeyValue<Foo, 'a'> 我可以创建与 Foo:s 属性的类型匹配的对象文字,但如果我没有专门为每个文字提供类型和键但是只需执行KeyValue<Foo, keyof Foo>,每个值将被允许属于Foo 中的任何值的类型,即所有值都将是string | number | boolean,而不是从输入的key 推断出来。
最后我希望能够做这样的事情:
const kvs: Array<KeyValue<Foo>> = [
{key: 'a', value: 'STRING'}, // should not compile if value is a number or boolean
{key: 'b', value: 42}, // should not compile if value is a string or boolean
{key: 'c', value: true}, // should not compile if value is a string or number
];
是否可以使用这些约束派生KeyValue 类型,从而在上面的第二个示例中有效地变为KeyValue<Foo, 'a'> | KeyValue<Foo, 'b'> | KeyValue<Foo, 'c'>,而无需手动编写此联合?基本上我想我想要的是能够从当前文字对象中key 的值推断value 的类型。
【问题讨论】:
标签: typescript typescript-generics