首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用类型记录枚举值创建新类型

使用类型记录枚举值创建新类型
EN

Stack Overflow用户
提问于 2019-07-01 19:06:04
回答 2查看 9K关注 0票数 20

我有以下情况:

代码语言:javascript
复制
enum FieldsMap {
  User = "user-name",
  Password = "user-password",
  Country = "user-country"
}

type Fields = "user-name" | "user-password" | "user-country";

如您所见,Fields正在重复FieldsMap的值,为了避免重复,Fields是否可以使用FieldsMap?此外,我在这里使用FieldsMap作为enum,但如果有必要,我可以更改它,我只是尽量避免使用字符串:

代码语言:javascript
复制
const onChangeHandler = (key: Fields, value: string) => {
  switch (key) {
    case FieldsMap.User:
      // do something with `value`
      break;
    case FieldsMap.Password:
      // do something with `value`
      break;
    case FieldsMap.Country:
      // do something with `value`
      break;
  }
};
EN

Stack Overflow用户

回答已采纳

发布于 2019-07-02 00:10:47

TS4.1+的更新:正如另一个答案指出的,现在可以使用模板文字类型获取FieldsMap枚举值的字符串表示形式:

代码语言:javascript
复制
type Fields = `${FieldsMap}`;
// type Fields = "user-name" | "user-password" | "user-country"

但重要的是要确保您确实需要这样做;enums的一般用例是,您不希望依赖于实际字符串文本值本身;对于名为Foo的枚举,类型Foo已经是枚举值的联合,但它们在名义上是处理的,因此您不能意外地使用字符串来代替它。如果您真的想使用字符串来代替值,那么您可能一开始就不想要一个enum,而应该只使用包含字符串文本的对象。关键是:在使用它之前,确保这是你真正想要的。

只是把这个写下来作为答案..。在TypeScript中,枚举本质上已经具备了您要寻找的行为,而不需要定义任何其他类型。

即,以下枚举定义:

代码语言:javascript
复制
enum Fields {
  User = "user-name",
  Password = "user-password",
  Country = "user-country"
}

将名为Fields的值引入范围,属性的键为UserPasswordCountry,其值分别为"user-name""user-password""user-country"。此值使其成为运行时,如下所示:

代码语言:javascript
复制
const x = Fields.User; // makes it to the emitted JS

并与以下值相似:

代码语言:javascript
复制
const FieldsLike = {
  User: "user-name",
  Password: "user-password",
  Country: "user-country"
} as const;

const xLike = FieldsLike.User; // makes it to the emitted JS;

但是,它也将一个名为Fields的类型引入范围,它等价于Fields对象中属性值的合并。当JS发出时,此类型与类型系统的其余部分一起是擦除,但在设计时可以通过类型注释和使用IntelliSense访问,如下所示:

代码语言:javascript
复制
const y: Fields = x; // the "Fields" annotation is the type

并且类似于

代码语言:javascript
复制
type FieldsLike = (typeof FieldsLike)[keyof typeof FieldsLike];
// type FieldsLike = "user-name" | "user-password" | "user-country"

const yLike: FieldsLike = xLike; // the "FieldsLike" annotation is the type

这是你要找的类型,见下文。

顺便说一句,枚举还充当一个名称空间,为每个enum成员导出类型:

代码语言:javascript
复制
const z: Fields.Password = Fields.Password; // type and value

(所以左边的Fields.Password是类型的名称,右边的Fields.Password是值的名称)。因此,在Fields下可访问的类型类似于名称空间:

代码语言:javascript
复制
namespace FieldsLike {
  export type User = typeof FieldsLike.User;
  export type Password = typeof FieldsLike.Password;
  export type Country = typeof FieldsLike.Country;
}

const zLike: FieldsLike.Password = FieldsLike.Password; // type and value

这意味着仅仅使用enum Fields { ... }定义就可以同时给出const FieldsLike = ...type FieldsLike = ...namespace FieldsLike的行为。

我们退后..。您正在寻找的类型,即Fields枚举下所有属性的联合类型,已经是一个名为Fields的类型。(好的,我将您的FieldsMap更改为Fields),您可以直接使用它:

代码语言:javascript
复制
const onChangeHandler = (key: Fields, value: string) => {
  switch (key) {
    case Fields.User:
      // do something with `value`
      break;
    case Fields.Password:
      // do something with `value`
      break;
    case Fields.Country:
      // do something with `value`
      break;
  }
};

好吧,希望能帮上忙。祝好运!

链接到代码

票数 44
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56841134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档