1.keyof
keyof返回的是,一个对象类型中,所有键名组成的联合类型。
键名,指键值对中的键。
联合类型,通常指|连接的类型。下面是联合类型的例子。
相对的,&连接的,是交叉类型。
//联合类型
let a1: string | number = 3
let a2: 1 | 2 | 3 = 3
搞懂了键和联合类型,自然就可以明白keyof运算符的含义。
type TypeObj = {
num: number,
str: string,
};
type Keys = keyof MyObj; // 'num'|'str'
注意,上面返回的是num和str字符串,组成的联合类型,并不是number之类的类型。
因为keyof返回的是键名。
2.extends?:
很多语言中,都会有三元运算符。ts中的extends,和三元运算符比较类似。
X extends Y ? A : B
这个表达式中,如果X是Y的子类型,则返回A,否则返回B。
什么是子类型呢?
直观来看,联合类型的某个类型,单独拿出来,属于这个联合类型的子类型。
type A1= string | number;
type A2 = string;
// A的类型为string
type A = A2 extends A1 ? string : number
let str:A = 'str';
比如接口呢?怎样才算子类型?
下面是一个有趣的例子。
interface A1 {
name: string
}
interface A2 {
name: string
age: number
}
// A的类型为string
type A = A2 extends A1 ? string : number;
let str:A = 'str';
这个例子中,A2接口比A1接口多了age。
A2可以再添加几个属性,或者保留name,将age改为其它属性,此时A2即为A1的子类型。
3.infer
infer翻译过来是推断。
ts一个常见的概念是类型推断,比如:
let myStr = 'oldstr'
myStr = 'newStr'
第一行中,ts已经推断出类型为string,所以oldStr变为newStr不会报错,都是string。
接下来,使用infer实现一个简易版的flatten,即拍平某数组类型(只拍平一层),用到了前面的extends。
type flatten<Type> =
Type extends Array<infer Item> ? Item : Type;
type x = [1,2,3];
type y = flatten<x>; // 1 | 2 | 3
let n: y = 3;
type Str = flatten<string[]>; //string
type Num = flatten<number>; //number
flatten函数用来拍平,x类型为数组,y类型即为x中元素组成的联合类型。
所以定义n为3,可以正常运行。
Str类型是string[]的元素,即为string。 number是数字不是数组,所以返回了本身。
4.[ ]
Y[X]:对象Y的X属性的类型。
type hhh={
hhh1:number
hhh2:string
};
type x = hhh['hhh1']; //number
5.in
in可以用来遍历联合类型。
type u = 'a'|'b'|'c';
//以下a,b两个类型相同
type a = {
[x in u]: number;
};
type b = {
a: number,
b: number,
c: number
};