基礎(chǔ)類型中簡(jiǎn)單介紹過(guò)枚舉傅蹂,用于將取值限定在一定范圍內(nèi)或定義一些不具有語(yǔ)義性的常量,使之可以清晰的表達(dá)意圖羊精。
數(shù)字枚舉
enum Colors {
red,
pink,
blue
}
編譯結(jié)果:
var Colors
;(function (Colors) {
Colors[(Colors['red'] = 0)] = 'red'
Colors[(Colors['pink'] = 1)] = 'pink'
Colors[(Colors['blue'] = 2)] = 'blue'
})(Colors || (Colors = {}))
枚舉成員的值默認(rèn)從 0 開(kāi)始自增改执,同時(shí)也會(huì)對(duì)枚舉值到枚舉名反向映射。
字符串枚舉
在一個(gè)字符串枚舉里髓棋,每個(gè)成員都必須用字符串字面量实檀,或另外一個(gè)字符串枚舉成員進(jìn)行初始化惶洲。不可以使用常量枚舉或計(jì)算值。
enum Colors {
red = 'RED',
pink = 'PINK',
blue = red
}
Colors.blue // 'RED'
編譯結(jié)果:
var Colors
;(function (Colors) {
Colors['red'] = 'RED'
Colors['pink'] = 'PINK'
Colors['blue'] = 'RED'
})(Colors || (Colors = {}))
由于字符串枚舉沒(méi)有自增行為劲妙,所以字符串枚舉可以很好的序列化湃鹊。 換句話說(shuō),數(shù)字枚舉的值通常并不能表達(dá)有用的信息(盡管反向映射會(huì)有所幫助)镣奋,但字符串枚舉允許提供一個(gè)運(yùn)行時(shí)有意義的并且可讀的值币呵,獨(dú)立于枚舉成員的名字。
手動(dòng)賦值
可以對(duì)單個(gè)或者全部枚舉成員手動(dòng)賦值侨颈。
當(dāng)對(duì)某個(gè)枚舉成員賦值后余赢,該枚舉之后未手動(dòng)賦值的枚舉項(xiàng)會(huì)接著遞增。
enum Colors {
red,
pink = 3,
blue
}
Colors.blue // 4
enum Colors {
red = 1,
pink = 3,
blue = 5
}
Colors.blue // 5
如果未手動(dòng)賦值的枚舉項(xiàng)與手動(dòng)賦值的重復(fù)了哈垢,TypeScript 編譯時(shí)不會(huì)進(jìn)行限制:
enum Colors {
red = 3,
pink = 1,
blue,
black,
orange
}
Colors.red // 3
Colors.black // 3
Colors[3] // 'black'
Colors[3] // 'black'
以上枚舉遞增到 3 的時(shí)候與前面的 red 的取值重復(fù)了妻柒,但是 TypeScript 并沒(méi)有報(bào)錯(cuò),導(dǎo)致 Colors[3] 的值先是 "red"耘分,而后又被 "black" 覆蓋举塔。編譯的結(jié)果是如下,所以使用的時(shí)候需要注意求泰,不要出現(xiàn)覆蓋的情況央渣。
var Colors
;(function (Colors) {
Colors[(Colors['red'] = 3)] = 'red'
Colors[(Colors['pink'] = 1)] = 'pink'
Colors[(Colors['blue'] = 2)] = 'blue'
Colors[(Colors['black'] = 3)] = 'black'
Colors[(Colors['orange'] = 4)] = 'orange'
})(Colors || (Colors = {}))
此外手動(dòng)賦值的枚舉項(xiàng)也可以為小數(shù)或負(fù)數(shù),之后未手動(dòng)賦值的項(xiàng)的遞增步長(zhǎng)仍為 1:
enum Colors {
red = 1.5,
pink,
blue,
black = -1,
orange
}
Colors.pink // 2.5
Colors.orange // 0
常數(shù)項(xiàng)和可計(jì)算成員
當(dāng)給某一個(gè)枚舉成員設(shè)置常量或計(jì)算所得值后渴频,其之后的成員必須手動(dòng)初始化芽丹。
可計(jì)算成員的意思就是:初始化枚舉成員時(shí),可使用表達(dá)式卜朗、函數(shù)等方式動(dòng)態(tài)求值拔第,還可以是對(duì)之前定義的常量枚舉成員的引用。
常數(shù)項(xiàng)
const num = 2
enum Colors {
pink = 4,
red = num,
blue = 7
}
以上將常量 num 賦值給枚舉成員 red场钉,則其之后的成員必須初始化蚊俺,否則編譯報(bào)錯(cuò):
const num = 2
enum Colors {
pink = 4,
red = num,
blue
}
// Enum member must have initializer.
計(jì)算所得值
function getNum() {
return 3
}
enum Colors {
red = 1,
blue = getNum(),
pink = 6
}
enum Colors {
red = 1,
blue = 'sina'.length,
pink = 6
}
反向映射
除了創(chuàng)建一個(gè)以屬性名做為對(duì)象成員的對(duì)象之外,數(shù)字枚舉的成員還具有反向映射逛万,從枚舉值到枚舉名春叫。如下:
enum Colors {
red
}
Colors.red // 0
Colors[0] // 'red'
編譯結(jié)果:
var Colors
;(function (Colors) {
Colors[(Colors['red'] = 0)] = 'red'
})(Colors || (Colors = {}))
ts 編譯生成的 js 代碼中,數(shù)字枚舉類型被編譯成一個(gè)對(duì)象泣港,包含正向映射( key -> value)和反向映射( value -> key)暂殖。
注意:字符串枚舉的成員不會(huì)生成反向映射。
異構(gòu)枚舉
枚舉可以混合字符串和數(shù)字成員(不建議)
enum Colors {
red = 'RED',
pink = 'PINK',
blue = 4
}
運(yùn)行時(shí)枚舉
枚舉在運(yùn)行時(shí)是真正存在的對(duì)象当纱,因?yàn)?ts 會(huì)將枚舉編譯成 js 對(duì)象呛每。
enum Colors {
red
}
function bar(obj, key) {
return obj[key]
}
bar(Colors, 'red')
編譯結(jié)果:
var Colors
;(function (Colors) {
Colors[(Colors['red'] = 0)] = 'red'
})(Colors || (Colors = {}))
function bar(obj, key) {
return obj[key]
}
bar(Colors, 'red')
const(常量)枚舉
常量枚舉通過(guò)在枚舉上使用 const 修飾符來(lái)定義。
const enum Colors {
red = 4
}
function bar() {
return Colors.red
}
bar() // 4
常量枚舉與普通枚舉不一樣它會(huì)在編譯階段被刪除坡氯。因?yàn)槠胀杜e會(huì)被編譯成 js 對(duì)象晨横,可以將常量枚舉理解成在編譯階段首先生成 js 對(duì)象洋腮,然后將所有的枚舉值計(jì)算出來(lái),然后刪除對(duì)象手形。
編譯結(jié)果:
function bar() {
return 4 /* red */
}
bar()
所以在運(yùn)行時(shí)不可以使用常量枚舉啥供。比如:
const enum Colors {
red
}
console.log(Colors)
// 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.
// ("const" 枚舉僅可在屬性、索引訪問(wèn)表達(dá)式库糠、導(dǎo)入聲明的右側(cè)伙狐、導(dǎo)出分配或類型查詢中使用。)
聯(lián)合枚舉與枚舉成員的類型
首先解釋字面量枚舉成員瞬欧。
字面量枚舉成員是指不帶有初始值的常量枚舉成員贷屎,或者是值被初始化為以下三種情況的枚舉成員。
- 任何字符串字面量;
- 任何數(shù)字字面量
- 應(yīng)用了一元
-
符號(hào)的數(shù)字字面量
- 不帶有初始值的常量枚舉成員
enum Colors {
red
}
- 任何字符串字面量:
enum Colors {
red = 'RED'
}
- 任何數(shù)字字面量:
enum Colors {
red = 1
}
- 應(yīng)用了一元
-
符號(hào)的數(shù)字字面量:
enum Colors {
red = -10
}
當(dāng)所有枚舉成員都擁有字面量枚舉值時(shí)艘虎,枚舉成員或枚舉可以當(dāng)作類型使用唉侄。
枚舉成員類型
枚舉成員類型是指將枚舉的某些成員當(dāng)作類型使用。
enum Colors {
red = 'RED'
pink = 'PINK'
}
interface Tomato {
color: Colors.red
}
const tomato: Tomato = {
color: Colors.red
// color: Colors.pink
// Type 'Colors.pink' is not assignable to type 'Colors.red'.
}
枚舉類型
枚舉類型本身變成了每個(gè)枚舉成員的聯(lián)合類型野建。
enum Colors {
red = 'RED',
pink = 'PINK'
}
interface IColor {
color: Colors
}
const tomato: IColor = {
color: Colors.red
}