TypeScript:基于来自枚举的对象键进行键入

时间:2018-10-30 19:12:52

标签: typescript typescript-typings

我有一个枚举。我想使用其值为这些值成为键的对象创建类型。下面的示例演示了我想要实现的目标:

Dim filesToDrag As String() = {"\\Path\to\file"}
Me.DoDragDrop(New DataObject(DataFormats.FileDrop, filesToDrag), DragDropEffects.All)

它工作正常,但我想避免重复界面中enum的所有属性。

是否可以执行以下操作:

export enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

export interface MyInterface {
  property: {
    "prop 1": boolean,
    "prop 2": boolean,
    // ... more props
  }
}

更新:

感谢@jcalz解决方案:

export enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

// PSEUDOCODE!
export interface MyInterface {
  property: {
    [values from MyEnum]: boolean
  }
}

根据我之前写的内容,它很好用,但是我刚刚意识到我忘了提到我需要所有这些属性都是可选的。

如果实现enum MyEnum { PROP_1 = "prop 1", PROP_2 = "prop 2", // ... more props } interface PropertyInterface extends Record<MyEnum, boolean> {} interface MyInterface { property: PropertyInterface, } 的变量定义如下,则给定的解决方案将起作用:

MyInterface

但是如果我按如下所示省略一些键,将无法正常工作:

// VALID!
const myVariable: MyInterface = {
  property: {
    "prop 1": true,
    "prop 2": true,
  },
};

1 个答案:

答案 0 :(得分:4)

作为expanded key support mapped types的一部分,在TypeScript 2.9中添加了对此的支持。具体来说:

  

映射类型{ [P in K]: XXX }允许将任何K分配给string | number | symbol

这意味着您可以使用枚举值作为关键字为mapped type设置类型别名:

enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

type MyEnumValuedKeys = { [K in MyEnum]: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1": boolean;
//  "prop 2": boolean;
//  ... more props
// }

您可以通过在类似索引的键之后添加?来使映射类型属性为可选:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1"?: boolean;
//  "prop 2"?: boolean;
//  ... more props
// }

因此,您可以将OptionalMyEnumValuedKeys用作PropertyInterface。它是type alias,而不是接口。该usually doesn't matter,但如果情况确实如此,TypeScript 2.8引入了extend certain concrete mapped types的功能,因此您可以获得这样的界面:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; };
interface PropertyInterface extends OptionalMyEnumValuedKeys {} // add no properties

这也可以通过使用内置的RecordPartial类型别名来实现:

interface PropertyInterface extends Partial<Record<MyEnum, boolean>> {}

好的,希望能有所帮助。祝你好运!