如何在 TypeScript 中创建类似枚举的类型?

我正在为用于 TypeScript 的 Google 地图 API 创建一个定义文件。

我需要定义一个类似枚举的类型,例如 google.maps.Animation,它包含两个属性: BOUNCEDROP

在 TypeScript 中应该如何做到这一点?

173082 次浏览

从 TypeScript 0.9(目前是 alpha 版本)开始,您可以像下面这样使用枚举定义:

enum TShirtSize {
  Small,
  Medium,
  Large
}


var mySize = TShirtSize.Large;

默认情况下,这些枚举将分别分配0、1和2。如果要显式设置这些数字,可以将其作为枚举声明的一部分。

清单6.2具有显式成员的枚举

enum TShirtSize {
  Small = 3,
  Medium = 5,
  Large = 8
}


var mySize = TShirtSize.Large;

这两个例子都是直接从 JavaScript 程序员的 TypeScript中提取出来的。

请注意,这与0.8规范不同。0.8规范看起来像这样——但它被标记为实验性的,并且可能会改变,所以你必须更新任何旧的代码:

免责声明 -这个0.8的例子在 TypeScript 编译器的新版本中会被破坏。

enum TShirtSize {
Small: 3,
Medium: 5,
Large: 8
}


var mySize = TShirtSize.Large;

TypeScript 0.9 + 有一个枚举规范:

enum AnimationType {
BOUNCE,
DROP,
}

最后一个逗号是可选的。

只是另一个注意事项,您可以使用以下命令来创建 id/string 枚举:

class EnumyObjects{
public static BOUNCE={str:"Bounce",id:1};
public static DROP={str:"Drop",id:2};
public static FALL={str:"Fall",id:3};




}

现在这是语言的一部分。有关这方面的文档,请参阅 Typescriptlang.org > 基本类型 > 枚举。关于如何使用这些枚举的文档摘录如下:

enum Color {Red, Green, Blue};
var c: Color = Color.Green;

或手动背书号码:

enum Color {Red = 1, Green = 2, Blue = 4};
var c: Color = Color.Green;

还可以使用例如 Color[2]返回到枚举名称。

下面的例子说明了这一切是如何整合在一起的:

module myModule {
export enum Color {Red, Green, Blue};


export class MyClass {
myColor: Color;


constructor() {
console.log(this.myColor);
this.myColor = Color.Blue;
console.log(this.myColor);
console.log(Color[this.myColor]);
}
}
}


var foo = new myModule.MyClass();

这将记录:

undefined
2
Blue

因为,在写这篇文章的时候,Typescript Playground 会生成这样的代码:

var myModule;
(function (myModule) {
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(myModule.Color || (myModule.Color = {}));
var Color = myModule.Color;
;
var MyClass = (function () {
function MyClass() {
console.log(this.myColor);
this.myColor = Color.Blue;
console.log(this.myColor);
console.log(Color[this.myColor]);
}
return MyClass;
})();
myModule.MyClass = MyClass;
})(myModule || (myModule = {}));
var foo = new myModule.MyClass();

更新 :

正如@iX3所指出的,打字稿2.4支持枚举字符串。

见: 在 Typescript 创建一个具有字符串值的枚举


原答案:

对于 String 成员值,TypeScript 只允许数字作为枚举成员值。但是有一些解决方案/技巧你可以实现;

解决方案1:

复制自: https://blog.rsuter.com/how-to-implement-an-enum-with-string-values-in-typescript/

有一个简单的解决方案: 只需在赋值之前将字符串文字强制转换为 any:

export enum Language {
English = <any>"English",
German = <any>"German",
French = <any>"French",
Italian = <any>"Italian"
}

解决方案2:

复制自: https://basarat.gitbooks.io/typescript/content/docs/types/literal-types.html

可以使用字符串文字作为类型。例如:

let foo: 'Hello';

在这里,我们创建了一个名为 foo 的变量,该变量只允许向其分配字面值‘ Hello’。这表现如下:

let foo: 'Hello';
foo = 'Bar'; // Error: "Bar" is not assignable to type "Hello"

它们本身并不十分有用,但是可以组合在一个类型联合中,以创建一个强大(且有用)的抽象,例如:

type CardinalDirection =
"North"
| "East"
| "South"
| "West";


function move(distance: number, direction: CardinalDirection) {
// ...
}


move(1,"North"); // Okay
move(1,"Nurth"); // Error!

打字稿中的枚举:

枚举被放入类型脚本语言中以定义一组命名常量。使用枚举可以使我们的生活更容易。原因是这些常量通常比枚举表示的值更容易读取。

创建枚举:

enum Direction {
Up = 1,
Down,
Left,
Right,
}

这个来自类型脚本文档的示例非常好地解释了枚举是如何工作的。注意,我们的第一个枚举值(Up)用1初始化。数字枚举的所有以下成员都是这个值的 自动增量(即 Down = 2,Left = 3,Right = 4)。如果我们没有用1初始化第一个值,枚举将从0开始,然后自动递增(即 Down = 1,Left = 2,Right = 3)。

使用枚举:

我们可以通过以下方式访问枚举的值:

Direction.Up;     // first the enum name, then the dot operator followed by the enum value
Direction.Down;

请注意,这样我们在编写代码的方式上更像是 描述性的。枚举基本上阻止我们使用 神奇的数字(表示某个实体的数字,因为程序员在某个上下文中赋予了它们某种意义)。神奇的数字之所以糟糕,是因为以下原因:

  1. 我们需要更深入地思考,首先需要将数字转换为一个实体,然后才能对代码进行推理。
  2. 如果我们在很长一段时间后检查我们的代码,或者其他程序员检查我们的代码,他们不一定知道这些数字是什么意思。

对我来说,输入像下面这样的枚举是可行的(这也允许您将它作为一个对象进行循环) :

enum: { [x: string]: string }

地图例子:

export const yourFunction = (
enum: { [x: string]: string },
) => {
const iHaveBeenMapped = Object.keys(enum).map((key) => {
const enumValue = enum[key];
});
}