具有有效属性名称列表中只有一个属性的对象的类型

时间:2018-12-04 21:52:07

标签: typescript

如何在不创建包含每个可能对象的联合类型的情况下对此建模?

type ValidRootPropertyNames =
  'Property1' |
  'Property2';

type ObjectWithRootPropertyNameFromList =
  { Property1: string; } |
  { Property2: string; };

const obj1: ObjectWithRootPropertyNameFromList = { // okay
  Property1: 'foo',
};

const obj2: ObjectWithRootPropertyNameFromList = { // okay
  Property2: 'foo',
};

const obj3: ObjectWithRootPropertyNameFromList = { // error
  Property3: 'foo',
};

以上内容满足了我们的需求;问题是,当有许多有效的属性名称时,它变得很麻烦。

1 个答案:

答案 0 :(得分:1)

您可以使用distributive behavior of conditional types通过键的并集自动创建并集:

type ValidRootPropertyNames =
'Property1' |
'Property2';

type ObjectWithRootPropertyNameFromList =
    ValidRootPropertyNames extends infer T ? // Introduce a type parameter to have distributive behavior 
    T extends string ? Record<T, string> : never : never;

const obj1: ObjectWithRootPropertyNameFromList = { // okay
    Property1: 'foo',
};

const obj2: ObjectWithRootPropertyNameFromList = { // okay
    Property2: 'foo',
};

const obj3: ObjectWithRootPropertyNameFromList = { // error
    Property3: 'foo',
};