3.13 枚举类型
枚举的功能类似于字面量类型+联合类型组合的功能,也可以表示一组明确的可选值。
枚举:定义一组命名常量。它描述一个值,该值可以是这些命名常量中的一个。
enum Direction { Up, Down, Left, Right }
function changeDirection(direction: Direction) {
console.log(direction)
}
解释:
- 使用enum关键字定义枚举。
- 约定枚举名称,枚举中的值以大写字母开头。
- 枚举中的多个值之间通过 ,(逗号)分隔。
- 定义好枚举后,直接使用枚举名称作为类型注解。
1.访问枚举成员
注意:形参direction的类型为枚举Direction,那么,实参的值就应该是枚举Direction成员的任意一个。
enum Direction { Up, Down, Left, Right }
function changeDirection(direction: Direction) {
console.log(direction)
}
changeDirection(Direction.Up) //访问枚举成员
解释:类似于JS中的对象,直接通过点(.)语法访问枚举的成员。
2.枚举成员的值
解释:通过将鼠标移入Direction.Up,可以看到枚举成员Up的值为0。
注意:枚举成员是有值的,默认为:从0开始自增的数值。
3.数字枚举
我们把枚举成员的值为数字的枚举,称为:数字枚举。
当然,也可以给枚举中的成员初始化值。
// Down -> 11, Left -> 12, Right -> 13
enum Direction { Up = 10, Down, Left, Right }
enum Direction{ Up = 2, Down = 4, Left = 8, Right = 16 }
4.字符串枚举
字符串枚举:枚举成员的值是字符串。
enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
注意:字符串枚举是没有自增长行为,因此,字符串枚举中的每个成员都必须有初始值。
5.枚举的特性以及实现原理
枚举是TS中为数不多的非JavaScript类型级扩展(不仅仅是类型)的特性之一。
因为:其他类型仅仅被当作类型,而枚举不仅用作类型,还提供值(枚举成员都是有值的)。
也就是说,其他类型会在编译为JS代码时自动移除。但是,枚举类型会被编译成JS代码!(意味着需要更多的开销)
3.14 any类型
原则:不推荐使用any!这会让TypeScript变为“AnyScript”(失去TS类型保护的优势)。
因为当值的类型为any时,可以对该值进行任意操作,并且不会有代码提示。
let obj: any = { x: 0 }
// { x: 0 }本质是一个对象
obj.bar = 100 // 访问obj中不存在的bar属性甚至给bar赋值
obj() // 把obj当成函数来调用
const n: number = obj // 把obj赋值给number类型的变量n
// 以上的操作都会导致错误,但由于obj是any类型,所以TS并不会有错误提示以及类型保护
解释:以上操作都不会有任何类型错误提示,即使可能存在错误!
尽可能的避免使用any类型,除非临时使用any来“避免”书写很长,很复杂的类型!
其他隐式具有any类型的情况:1.声明变量不提供类型也不提供默认值
let a
a = 1
a = ''
a()
// 均不报错,变量a隐式具有any类型
2.函数参数不加类型。
function add(num1, num2) { }
add(1, 2)
add(1, '0')
add(1, false)
// 均不报错,函数add()的参数num1和num2隐式具有any类型
注意:因为不推荐使用any,所以,这两种情况下都应该提供类型。
3.15 typeof操作符
众所周知,JS中提供了typeof操作符,用来在JS中获取数据的类型。
console.log(typeof "Hello world") //打印出 string
实际上,TS也提供了typeof操作符:可以在类型上下文中引用变量或属性的类型(类型查询)。
使用场景:根据已有变量的值,获取该值的类型,来简化类型的书写。
let p = { x: 1, y: 2 }
function formatPoint(point: { x: number; y: number }) {}
formatPoint(p)
let p = { x: 1, y: 2 }
function formatPoint(point: typeof p) {}
// 这里typeof所处的环境就是类型上下文环境
// 这里是将变量 p的类型用作函数formatPoint()中变量point的类型
解释:
- 使用 typeof 操作符来获取变量p的类型,结果与第一种(对象字面量形式的类型)相同。
- typeof 出现在类型注解的位置(参数名称冒号的后面)所处的环境就在类型上下文(区别于JS代码)。
- 注意: typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函数调用的类型,即函数返回值类型)。
let p = { x: 1, y: 2 }
let num: typeof p.x
// 查询p对象中属性x的类型 --> 变量num的类型为number