如何在打字稿中键入枚举变量?

Posted

技术标签:

【中文标题】如何在打字稿中键入枚举变量?【英文标题】:How do you type an enum variable in typescript? 【发布时间】:2018-09-18 07:50:02 【问题描述】:

我在关于如何访问 html 中的枚举的各种 *** 答案中看到说要在组件上定义一个变量并将其设置为等于枚举,就像在这个 question 中一样。但是,类型是什么?

使用他们的例子:

enum MyEnum
  First,
  Second


export class MyComponent
  MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...


<div [ngSwitch]="myEnumVar">
  <div *ngSwitchCase="MyEnum.First"><app-first-component></app-first-component></div>
  <div *ngSwitchCase="MyEnum.Second"><app-second-component></app-second-component></div>
  <div *ngSwitchDefault>MyEnumVar myEnumVar is not handled.</div>
</div>

myEnumVar 已输入,但 MyEnum 未输入。我应该输入什么?

【问题讨论】:

【参考方案1】:

因为枚举被创建为普通的,所以它们的类型实际上是object

例如枚举:

enum MyEnum
  First,
  Second

transpiled to:

var MyEnum;
(function (MyEnum) 
    MyEnum[MyEnum["First"] = 0] = "First";
    MyEnum[MyEnum["Second"] = 1] = "Second";
)(MyEnum || (MyEnum = ));
           // ^^^^^^^^^^^ --- important part

注意 MyEnum 最终是一个对象 (),稍后添加了属性。更具体地说,使用 number 键和 string 值(见下文)。

所以,如果你想声明一个类型,你有一些选择。

对于初学者,您可以使用objectany,如下所示(但也请检查其他选项):

export class MyComponent
  MyEnum:Object = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...

索引签名类型

另一个选项,对于枚举,你也可以使用类型 [s: number]: number | string:

export class MyComponent
  MyEnum:[s: number]: number | string = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...

typeof

或者,如pointed by Gerrit0 (see their answer for the full info and due credits):

export class MyComponent
  MyEnum:typeof MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...

【讨论】:

感谢@acdcjunior 的详细回答,它奏效了。您介意分解 [s: number]: string 的含义吗?为什么不反转,比如[s: string]: number,因为枚举是以字符串为键的数字? 一些注意事项 - 1. 不要使用Object,而是使用object。 Docs。 2.typeof Enum比索引类型更正确。 @Gerrit0 感谢您的回答和评论。我已经更新它以保持准确。 (猜猜这就是我在这些情况下应该做的......) @evereveron 是的,从结构上讲,这就是枚举,以数字作为键的对象(尽管它们也将字符串作为键 O_o)和数字/字符串作为值。【参考方案2】:

虽然 acdcjunior 的回答在技术上是正确的 - 是的,枚举是一个对象,是的,它可以用 [s: number]: string 类型来描述,但这不是你应该键入 MyEnum 属性的方式。

枚举同时包含字符串和数字值,因此索引签名至少应该是 [s: number]: string | number - MyEnum[1] === "First"MyEnum.First === 1

然而,TypeScript 提供了一种更好的方法,即typeof 运算符。这与 javascripttypeof 不同 - 当您在类型声明中使用 typeof 时,它会获取值的类型,并且不受原语和 object 的限制。

为了突出区别,这里有一个例子:

enum MyEnum 
  First,
  Second


class MyComponent 
  static MyEnum: typeof MyEnum = MyEnum
  static MyObjectEnum:  [s: number]: string | number  = MyEnum


// a is `any`
// can't use MyComponent.MyObjectEnum.First
let a = MyComponent.MyObjectEnum['First']
// b is `MyEnum`
let b = MyComponent.MyEnum['First'] // or MyComponent.MyEnum.First
// c is `any`
let c = MyComponent.MyObjectEnum['Third']
// d is `any`
// using MyComponent.MyEnum.Third catches this error
let d = MyComponent.MyEnum['Third']
// neither catch this error
// e is type `string`
// f is type `string | number`
let e = MyComponent.MyEnum[3]
let f = MyComponent.MyObjectEnum[3]

如果您在尝试键入内容时查看 IDE 推断的类型,您可以了解很多关于应该使用哪些类型的信息。

【讨论】:

以上是关于如何在打字稿中键入枚举变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中访问枚举的名称

在打字稿中扩展枚举

如何在打字稿中声明全局变量

在打字稿中键入注释[重复]

如何在变量打字稿中动态设置当前时间

打字稿:如何检查一个值是不是是有效的枚举键值? [复制]