5分种学会:常见的ts类型运算符

242 阅读2分钟

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
};