Skip to content

Typescript 枚举与类型兼容 ​

一、枚举 ​

数字枚举 ​

默认从 0 开始递增:

ts
enum Status {
  Uploading,   // 0
  Success,     // 1
  Failed,      // 2
}
enum Status {
  Uploading,   // 0
  Success,     // 1
  Failed,      // 2
}

可以指定初始值,后面的值自动递增:

ts
enum Status {
  Uploading = 2,
  Success,     // 3
  Failed,      // 4
}
enum Status {
  Uploading = 2,
  Success,     // 3
  Failed,      // 4
}

初始值可以是常量或函数计算值(计算值后的成员必须手动赋值):

ts
const test = 2
const getIndex = (): number => 2

enum Status {
  Uploading = test,
  Success = getIndex(),
  Failed = 2,   // 必须手动赋值
}
const test = 2
const getIndex = (): number => 2

enum Status {
  Uploading = test,
  Success = getIndex(),
  Failed = 2,   // 必须手动赋值
}

字符串枚举 ​

ts
enum Message {
  Error = 'sorry error',
  Success = 'success',
  Fail = Error,  // 可以使用其他成员
}
enum Message {
  Error = 'sorry error',
  Success = 'success',
  Fail = Error,  // 可以使用其他成员
}

异构枚举 ​

混合数字和字符串,非必要不建议使用:

ts
enum Result {
  Failed = 0,
  Success = 'success',
}
enum Result {
  Failed = 0,
  Success = 'success',
}

枚举成员类型和联合枚举类型 ​

ts
enum Animal {
  Dog = 1,
  Cat = 2,
}
interface Dog {
  type: Animal.Dog   // 枚举成员作为类型
}
const dog: Dog = { type: Animal.Dog }

enum Status { Off, On }
interface Light {
  status: Status     // 联合枚举类型
}
enum Animal {
  Dog = 1,
  Cat = 2,
}
interface Dog {
  type: Animal.Dog   // 枚举成员作为类型
}
const dog: Dog = { type: Animal.Dog }

enum Status { Off, On }
interface Light {
  status: Status     // 联合枚举类型
}

const 枚举 ​

编译后直接替换为常量值,不会生成对象:

ts
const enum Status {
  Success = 200,
}
const s = Status.Success
// 编译后:var s = 200
const enum Status {
  Success = 200,
}
const s = Status.Success
// 编译后:var s = 200

外部枚举 ​

使用 declare 声明,只用于编译检查,编译结果中删除:

ts
declare enum Directions {
  Up, Down, Left, Right,
}
declare enum Directions {
  Up, Down, Left, Right,
}

二、类型推论与兼容性 ​

类型推论 ​

ts
let str = 'haha'   // 推断为 string
str = 1            // 报错

let arr = [1, 'a'] // 推断为 (string | number)[]
let str = 'haha'   // 推断为 string
str = 1            // 报错

let arr = [1, 'a'] // 推断为 (string | number)[]

函数类型兼容 ​

参数个数:右边的参数个数必须 ≤ 左边的参数个数:

ts
let x = (a: number) => 0
let y = (b: number, c: number) => 0
y = x  // 正常
x = y  // 报错
let x = (a: number) => 0
let y = (b: number, c: number) => 0
y = x  // 正常
x = y  // 报错

枚举类型兼容 ​

枚举与数字兼容,但不同枚举之间不兼容:

ts
enum Status { On, Off }
enum Animal { Dog, Cat }
let s = Status.On
s = Animal.Dog  // 报错
enum Status { On, Off }
enum Animal { Dog, Cat }
let s = Status.On
s = Animal.Dog  // 报错

类的类型兼容 ​

比较实例上的成员类型,私有成员必须来自同一个类:

ts
class ParentClass {
  private age: number
  constructor() {}
}
class ChildrenClass extends ParentClass {
  constructor() { super() }
}
class OtherClass {
  private age: number
  constructor() {}
}
const p: ParentClass = new ChildrenClass()  // 正常
const o: ParentClass = new OtherClass()     // 报错
class ParentClass {
  private age: number
  constructor() {}
}
class ChildrenClass extends ParentClass {
  constructor() { super() }
}
class OtherClass {
  private age: number
  constructor() {}
}
const p: ParentClass = new ChildrenClass()  // 正常
const o: ParentClass = new OtherClass()     // 报错