繁体   English   中英

从 object 类型创建键/值类型

[英]Create key/value type from object type

假设我们有一个类型

type Foo = {
  a: string;
  b: number;
  c: boolean;
}

我现在想为一个 object 定义一个类型,它有一个key和一个给定类型Tvalue ,这样值的类型就可以直接从键中推断出来,这样我就可以这样做:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM