一、概念
使用枚舉我們可以定義一些帶名字的常量。
我理解的是使用枚舉,可以解決我們在項目中定義常量不規范的問題。
-
數字枚舉
// 使用初始化器 enum Direction { // 定義數字枚舉 Up = 1, // 使用初始化器,初始值1 Down, // 2 Left, // 3 Right // 4 // ...定義依次遞增 } // 不使用初始化器 enum Direction { Up, // 0 Down, // 1 Left, Right, }通過枚舉的屬性來訪問枚舉成員,和枚舉的名字來訪問枚舉類型
enum Response { No = 0, Yes = 1, } function respond(recipient: string, message: Response): void { console.log(recipient + ' ' + message); } respond("Princess Caroline", Response.Yes) // Princess Caroline 1 respond("Princess Caroline", 1000) // Princess Caroline 1000 這里值沒有在Response里定義也不報錯 respond("Princess Caroline", 'df') // error 類型“"df"”的參數不能賦給類型“Response”的參數。ts(2345)數字枚舉中使用函數計算得出的常量成員,后面緊跟著的常量成員必須使用常量進行初始化。
function getSomeValue(): number { return 123 } enum E { A = getSomeValue(), B = 1, // error! 前面的'A'不是常量初始化的,所以'B'需要一個初始化器 C // 2 no error } -
字符串枚舉
在一個字符串枚舉里,每個成員都必須用字符串字面量,或另外一個字符串枚舉成員進行初始化。
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT", } -
異構枚舉
enum BooleanLikeHeterogeneousEnum { // 不建議這樣使用 No = 0, Yes = "YES", } -
計算的成員和常量成員
-
它是枚舉的第一個成員且沒有初始化器,這種情況下它被賦予值 0
// E.X is constant: enum E { X // 0 } -
它不帶有初始化器且它之前的枚舉成員是一個 數字常量。 這種情況下,當前枚舉成員的值為它上一個枚舉成員的值加1。
enum E2 { A = 1, B, // 2 C // 3 } -
枚舉成員使用 常量枚舉表達式初始化。
使用規則:
一個枚舉表達式字面量(主要是字符串字面量或數字字面量)
一個對之前定義的常量枚舉成員的引用(可以是在不同的枚舉類型中定義的)
帶括號的常量枚舉表達式
一元運算符 +, -, ~其中之一應用在了常量枚舉表達式
常量枚舉表達式做為二元運算符 +, -, *, /, %, <<, >>, >>>, &, |, ^的操作對象
若常數枚舉表達式求值后為 NaN或 Infinity,則會在編譯階段報錯。enum FileAccess { // constant members None, Read = 1 << 1, Write = 1 << 2, ReadWrite = Read | Write, // computed member G = "123".length }
-
枚舉成員成為類型
enum ShapeKind { Circle, Square, } interface Circle { kind: ShapeKind.Circle; radius: number; } interface Square { kind: ShapeKind.Square; sideLength: number; } let c: Circle = { kind: ShapeKind.Square, // Error! // kind: 1, no error // kind: 123, no error // kind: 'str', // 不能將類型“string”分配給類型“ShapeKind.Circle”。 radius: 100, }短路問題
enum E { Foo, Bar } function f(x: E) { if (x !== E.Foo || x !== E.Bar) { // 判斷無意義,總是會通過第一個判斷 // ~~~~~~~~~~~ // Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'. console.log(x); } } -
將枚舉當作參數傳入函數中
枚舉對象
enum E { X, Y, Z } function f(obj: { X: number }) { return obj.X; // Works, since 'E' has a property named 'X' which is a number. } console.log(f(E)); // 0反向映射:從枚舉值到枚舉名字。
enum Enum { A } let a = Enum.A; let nameOfA = Enum[a]; // "A"生成的代碼中,枚舉類型被編譯成一個對象,它包含了正向映射( name -> value)和反向映射( value -> name)。 引用枚舉成員總會生成為對屬性訪問并且永遠也不會內聯代碼。
要注意的是 不會為字符串枚舉成員生成反向映射。
-
const枚舉
減少重復代碼定義產生的代碼量開銷
避免非直接的對枚舉成員的訪問const enum Enum { A = 1, B = A * 2 }常量枚舉只能使用常量枚舉表達式,并且不同于常規的枚舉,它們在編譯階段會被刪除。
常量枚舉成員在使用的地方會被內聯進來。
常量枚舉不允許包含計算成員。// 使用常量枚舉 const enum Directions { Up, Down, Left, Right } let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right] // [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */] // 使用計算初始化枚舉成員 function getval() { return 123 } enum Directions { Up = getval(), Down = 1 } let directions = [Directions.Up, Directions.Down] // [123, 1] -
外部枚舉
外部枚舉用來描述已經存在的枚舉類型的形狀。
declare enum Enum { // 沒有完全弄懂這個declare,據網上博文描述, A = 1, B, C = 2 }外部枚舉和非外部枚舉之間有一個重要的區別,在正常的枚舉里,沒有初始化方法的成員被當成常數成員。 對于非常數的外部枚舉而言,沒有初始化方法時被當做需要經過計算的。
浙公網安備 33010602011771號