Appearance
高级
枚举
数字枚举
typescript
enum Status {
Uploading,
Success,
Failed,
}
console.log('Status.Uploading', Status.Uploading) // 0
console.log('Status["Success"]', Status['Success']) // 1
console.log('Status.Failed', Status.Failed) // 2
枚举默认编码为 0,但允许手动指定,此时如果指定 Success = 0,则 Status 的三个状态分别是 0,0,1
数字枚举允许使用计算值或者常量对其中元素进行值定义, 但元素后一位必须手动指定初始值
反向映射
一个枚举,不仅可以通过字段名得到枚举值,也可以通过枚举值得到字段名,查看一个枚举的内容:
字符串枚举
字符串枚举成员必须初始化枚举值,同时不能引入计算值\
typescript
const test2 = 'test2'
enum Message {
Success = 'Hai, Success',
Error = 'Sorry, Error',
Failed = Error, // 可以使用自身的成员来当做枚举值 实际输出 Sorry, Error
}
异构枚举(不推荐使用)
枚举值有字符串类型和数字类型混合的,就叫做异构枚举.
枚举成员类型和联合枚举类型
当一个枚举值满足一定条件的时候,那么它的枚举值和枚举值成员都可以当做类型来使用.
- 没有初始值的枚举类型
enum E {A,B,C}
- 枚举值类型为字符串字面量的类型
enum E { A='a',B='b'}
- 枚举值为数字类型且不包含计算类型
enum E {A=1, B=5}
typescript
enum Animals {
Dog,
Cat,
}
interface Dog {
type: Animals.Dog
}
const dog: Dog = {
type: Animals.Dog, // 等价于 0
}
console.log('dog', dog) // dog { type: 0 }
const enum
枚举是在运行时真正存在的一个对象。 其中一个原因是因为这样可以从枚举值到枚举名进行反向映射。
然而有时候需求却比较严格。 当访问枚举值时,为了避免生成多余的代码和间接引用,可以使用常数枚举。 常数枚举是在enum
关键字前使用const
修饰符。不同于常规的枚举的是它们在编译阶段会被删除
所以常数枚举不可能有计算成员。
类型推论
基础
多类型联合
上下文类型
ts 推断出了 e 参数的数据类型是 MouseEvent
类型兼容性
基础
函数兼容性
- 参数个数
- 参数类型
- 返回值类型
可选参数和剩余参数
函数重载
typescript// 重载出现的条件:方法/函数名相同,参数类型不同 或者参数数量不同 或者参数顺序不同 function add(n: number, m: number): number function add(n: string, m: string): string function add(n: number, m: string): string function add(n: string, m: number): string function add(n: any, m: any): any { return n + m } console.log(add(2, 'hello')) console.log(add(2, 3))
this 类型
typescript
class Counter {
constructor(public count: number) {
this.count = count
}
add(value: number) {
this.count += value
return this // 返回 this 可以让类支持链式调用
}
sub(value: number) {
this.count -= value
return this
}
}
let count = new Counter(10)
console.log('count.add(5).sub(2)', count.add(5).sub(2))
索引类型
索引类型查询操作符
typescript
// 获取指定 key 的值 使用 ts 泛型对函数的参数进行约束,使第二个参数 K 必须为对象包含的 key
function getValue<T, K extends keyof T>(obj: T, names: K[]) {
return names.map(item => obj[item])
}
const infoObj = {
name: '猫南北',
age: 18,
}
let result = getValue(infoObj, ['name'])
console.log('result', result) // result [ '猫南北' ]
let result2 = getValue(infoObj, ['gender']) // Error: 不能将类型"gender"分配给类型"name"|"age"
索引访问操作符
typescript
type NameType = Info['name']
function getProperty<T, K extends keyof T>(obj: T, name: K): T[K] {
return obj[name]
}
let result3 = getProperty(infoObj, 'age')
console.log('result3', result3) // result3 18
映射类型
基础
typescript
// 也可以使用 Ts 内置类型中的 ReadOnly和Partial来快速实现
type myInfo = Readonly<Partial<Info>>
由映射类型进行推断
增加或移除特定修饰符
keyof 和映射类型在 2.9 的升级
元组和数组上的映射类型
条件类型
基础
typescript
interface Animal {
live(): void
}
interface Dog extends Animal {
woof(): void
}
type Example1 = Dog extends Animal ? true : false // Example1 = true
type Example2 = RegExp extends Animal ? true : false // Example2 = false
type IdLabel = number
type NameLabel = string
type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabel
function createLabel<T extends number | string>(nameOrId: T): NameOrId<T> {
throw ''
}
let a = createLabel('猫南北') // a:string
let b = createLabel(123) // b:number
条件约束类型
typescript
type MessageOf<T> = T['Message'] // 类型“"Message"”无法用于索引类型“T”。
type MessageOf<T extends { Message: unknown }> = T['Message']