一、何时使用 enum 类型
- 情况 1:做类型映射时(字符串和数字的映射)
// todo 写完值后,后面不写值则自动 +1 enum A { todo = 0, done, archived, deleted } const a: A = 1 // A.archived = 2 const c: A = A.archived - 情况 2:做权限校验时
enum Permission { None = 0, // 0000 Read = 1 << 0, // 0001 Write = 1 << 1, // 0010 Delete = 1 << 2, // 0100 Manage = Read | Write | Delete // 0111 } type User = { permission: Permission } const user:User = { permission: 0b0010 // 0b 代表二进制 } // user.permission & Permission.Write 就是 0b0010 & 0b0010 = 0b0010 if ((user.permission & Permission.Write) === Permission.Write) { console.log('我有写权限') } // user.permission & Permission.Manage 就是 0b0010 & 0b0111 = 0b0010 if ((user.permission & Permission.Manage) === Permission.Manage) { console.log('我有管理员权限') }
二、type 和 interface 的区别
- type 是类型别名(可以声明任意类型),interface 是产生一个新的类型
type Num1 = number type Num2 = Num1 // 这里 Num2 其实显示的是 number 并不是 Num1 所以 type 其实是类型的别名 const n1: Num1 = 1 const n2: Num2 = 2 type FalseLike = 0 | '' | false | null | undefined type Point = { x: number, y: number } const point: Point = { x: 1, y: 2 } type Points = Point[] const points: Points = [{x: 1, y: 2}] type Line = [Point, Point] const line: Line = [{x: 1, y: 2}, {x: 2, y: 3}] type Circle = { center: Point, radius: number } const circle: Circle = { center: {x: 1, y: 2}, radius: 3 } type Fn = (a: number, b: number) => number type FnWithProp = { (a: number, b: number): number prop: string } const fn: FnWithProp = (a, b) => a + b fn.prop = 'prop' - interface 是声明一个接口来描述对象的属性,type 可以声明任意类型
interface Point { x: number b: number } interface Points extends Array<Point> {} interface Fn { (a: number, b: number): number } interface FnWithProp { (a: number, b: number): number, prop: string } const f: FnWithProp = (a, b) => a+b f.prop = 'prop' - type 不能重新赋值,interface 可以,赋值后会合并
interface A { aa: number } interface A { bb: number } const numObj:A = { aa: 1, bb: 2 } - type 遇到冲突不会报错,interface 遇到冲突会报错(详见交叉类型章节)