TypeScript:基于来自枚举的对象键的类型 [英] TypeScript: typings based on object keys that come from enum

查看:38
本文介绍了TypeScript:基于来自枚举的对象键的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an enum. I'd like to use its values to create typings for an object where these values became keys. The following example demonstrates what I'd like to achieve:

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
  }
}

它工作正常,但我想避免在界面中重复枚举中的所有属性.

It works fine, but I'd like to avoid repeating all the properties from enum in the interface.

是否可以执行以下操作:

Is it possible to do something like:

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

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

<小时>

更新:

感谢@jcalz 的解决方案:

Thanks @jcalz for the solution:

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

interface PropertyInterface extends Record<MyEnum, boolean> {}

interface MyInterface {
  property: PropertyInterface,
}

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

It works good, according to what I wrote before, but I've just realized that I forgot to mention that I need all these properties to be optional.

如果实现 MyInterface 的变量定义如下,则给定的解决方案有效:

The given solution works if a variable that implements MyInterface is defined as follows:

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

但是如果我按如下方式省略一些键则不起作用:

But does not work if I omit some keys as follows:

// INVALID :(
const myVariable: MyInterface = {
  property: {
    "prop 1": true,
  },
};

推荐答案

TypeScript 2.9 中添加了对此的支持,作为 扩展键支持映射类型.具体:

Support for this was added in TypeScript 2.9 as part of expanded key support mapped types. Specifically:

映射类型 { [P in K]: XXX } 允许任何可分配给 string | 的 K数量 |符号.

A mapped type { [P in K]: XXX } permits any K assignable to string | number | symbol.

这意味着您可以为 映射类型创建类型别名 以枚举值作为键:

That means you can make a type alias to a mapped type with enum values as the key:

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
// }

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

You can make mapped type properties optional by adding a ? after the index-like key:

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

因此您可以使用 OptionalMyEnumValuedKeys 作为您的 PropertyInterface.它是一个类型别名,而不是一个接口.通常无关紧要如果确实如此,TypeScript 2.8 引入了扩展某些具体映射类型的能力,因此您可以得到这样的界面:

So you can use OptionalMyEnumValuedKeys as your PropertyInterface. It is a type alias and not an interface. That usually doesn't matter but in case it does, TypeScript 2.8 introduced the abilitity to extend certain concrete mapped types, so you can get an interface like this:

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

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

This could also be accomplished by using the built-in Record and Partial type aliases:

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

好的,希望有帮助.祝你好运!

Okay, hope that helps. Good luck!

这篇关于TypeScript:基于来自枚举的对象键的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆