⭐️ keyof
- 名称:索引类型查询操作符;
- 用途:对类型(interface或者type)进行操作;
- 解释:假设T是一个类型,那么
keyof T
产生的类型是T的属性名称字符串字面量类型构成的联合类型
。
interface Person {
name: string;
age: number;
address: string;
}
type keys = keyof Person;
//等价于 type keys = "name" | "age" | "address" ,
//除了字符的联合类型,也有可能有number的联合,因为对象的键位可以是字符或者数字
//有趣的是,当type Person=["a"]时,keys会是数组所有属性的字面量的联合类型,即keys="pop"|"push"......
如同keyof的名字,该操作符就是用来检测某个字符串参数或者变量是不是T的属性
注意当联合类型中含有never
的时候会自动将never剔除,也就是不会包括含有never的属性:
type b = never | "2" // 编译器自动认为b="2"
这是一个小知识点
⭐️ T[K]
- 名称:索引访问操作符;
- 用途:定义类型;
- 解释:该操作符依赖已经定义的某个类型T,或者在某个泛型T中使用,通过T的属性K得到T[K]类型。
interface A {
a: string,
b: "666"
}
type test1 = A["a"]; // 正确,test1=string
type test2 = A["b"]; // 正确,test2="666"
type test3 = A.a; // 报错,必须使用索引访问的方式
⭐️ ?
共有两种使用方式
一、在借口或者类型定义时使用
表示该属性为可选属性
type A = {
a: string,
b?: number,// b属性可选
}
二、在访问对象属性时使用
不为空链式访问符,变量不为null或undefined时返回该对象的属性或方法。
优点是省去对象为空的判断代码,尤其是目标为null和object的联合类型的时候。
class Person {
run = () => { }
}
class Test {
a: Person | null = null;
test() {
this.a?.run() //等价于:(this.a === null && this.b === undefined) ? undefined : this.a.run();
}
}
??
空合并运算符,当变量为null或者undefined时,取??后面的默认值。
let x = foo ?? bar();
// 等效于let x = (foo !== null && foo !== undefined) ? foo : bar();
注意,??
和||
的区别,??
在某些情况下,比如0
、''
、NaN
情况下不会取后面的默认值