[英]Create key/value type from object type
假设我们有一个类型
type Foo = {
a: string;
b: number;
c: boolean;
}
我现在想为一个 object 定义一个类型,它有一个key
和一个给定类型T
的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'>
我可以创建 object 与Foo
:s 属性类型匹配的文字,但是如果我没有具体提供每个文字的类型和键但是简单地做KeyValue<Foo, keyof Foo>
,每个值将被允许是Foo
中任何值的类型,即所有值都是string | number | boolean
string | number | boolean
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'>
KeyValue<Foo, 'a'> | KeyValue<Foo, 'b'> | KeyValue<Foo, 'c'>
上面第二个例子中的KeyValue<Foo, 'a'> | KeyValue<Foo, 'b'> | KeyValue<Foo, 'c'>
,而不必手动编写这个联合? 基本上我想我想要的是能够从当前文字 object 中的key
推断出value
的类型。
您不能使用单个KeyValue
object 表示每个键值对,因为这将需要部分推理(对于键)或以某种方式从同一 object 中的value
属性引用key
属性。
但是,您可以做的是使用输入 object 创建一个可区分的联合。
type Foo = {
a: string;
b: number;
c: boolean;
}
type KeyValue<T> = {
[P in keyof T]: {
key: P;
value: T[P];
}
}[keyof T];
// with KeyValue<Foo>, this generates the following type
//
// {
// key: "a";
// value: string;
// } | {
// key: "b";
// value: number;
// } | {
// key: "c";
// value: boolean;
// }
const kvs: Array<KeyValue<Foo>> = [
{key: 'a', value: 40}, // ERROR
{key: 'b', value: true}, // ERROR
{key: 'c', value: "foo"}, // ERROR
];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.