【知识网】TypeScript系统学习之高级类型详解,一起来复习吧

92 阅读3分钟

写在前面

以下这些TS的关键词,你认识哪些?你会用哪些?快一起来复习吧

TS关键词总结

  • type
  • interface
  • as
  • typeof
  • instanceof
  • keyof
  • readonly
  • infer
  • ...

内置类型:typescript/lib/lib.es5.d.ts

  • Readonly
  • Partial
  • Required
  • Pick
  • Record
  • Exclude
  • Extract
  • NonNullable
  • ReturnType
  • ...

综述

基础类型除了泛型之外,是TypeScript和JavaScript共有的,而高级类型是TypeScript所特有。

高级类型的作用:

  • 类型保护;
  • 类型区分;
  • 类型推导;

type 和 interface接口

type 定义一种类型变量,可以是任何类型; interface 定义一个对象类型, 可以通过implement实现;

接口用来实现时,可以规范类该有的属性和方法;

基本用法

// 类型声明
interface IA{
    id: number;
    name: string;
    list: IA[]; // IA类型数组
}
// 1.接口实现
class Student implement IA{
    constructor(id,name:string){
    }
}

// 2.类型使用
const orderList: IA[] = [...];
const doSome=(list:IA[]):IA[]=>{}; // 括号里面表示入参类型,括号外表示返回值类型

交叉类型和联合类型

交叉类型使用&符号表示,求交集,所以基本类型没有交叉类型,因为没有交集;联合类型使用|符号表示,求并集。

//交叉类型,求交集
type TA = IA & IB;
//联合类型,求并集
type TB = string | number;

类型断言:as

类型断言就是强制推断为某种类型,就可以使用该类型的具体属性和方法;


...
const list = doSome(aList as IA[]); 

image.png

类型保护:is

定义类型保护函数,其实就是做一次类型判断:

...
const isTeacher=(person: ITeacher | IStudent):person is ITeacher=>{
    // 根据p的xxx独有属性或方法是否存在来判断类型
    return (<ITeacher>person).teach !== undefined;
};

if(isTeacher(person)){
    person.teach();
}else{
    person.learn();
}

基本类型的判断可以使用typeof做类型判断,不用写类型保护函数;

typeof 和 instanceof

前面说过在进行类型判断时,typeof可以做基本类型的判断,而instanceof则可以通过构造函数来做判断,来实现类型保护;

instanceof 可以判断类

const person = getPerson();// 不确定返回Teacher类型还是Student类型
if(person instanceof Teacher){
   person.teach();
}

类型别名

别名大家应该都用过,就是起一个新的名字,一般用来区别已有变量,也可以通过命名,见名知意,少写些注释文案,这里就一笔带过。

// 普通别名
const { id:userId } = person;
// ts中别名
type Person<T> = {
    name:T
    parent: Person<T>
}

字面量类型

字面量就是常量值,一般在枚举值;

// 
type Profession ='teacher'|'doctor'|'programmer';
type Peason{
    getAge:()=> 1 | 2 | 3;
}

索引类型

索引类型,顾名思义就是对象或数组的索引形成一种类型。比如说指定某个泛型是另一个泛型的属性名的子集,使用 K extends keyof T,然后某个方法返回对应的属性值数组;

const pluck<T,K extends keyof T>(obj:T, names: K[]):T[K][]{
    return names.map(name=>obj[name])
}
// K表示一个属性名,那么T[K]就表示对应属性值,T[K][]则表示对应属性值数组

映射类型

映射类型,就是一个类型映射另一个类型。比如说TS关键词Readonly和Partial:

// 对象只读
type Readonly<T>={
    readonly [P in keyof T]: T[P];
}
// 对象可选
type Partial<T>={
    [P in keyof T]?: T[P];
}

类型推导

TypeScript会对一些已经赋值的变量,自动做类型推导;所以一些比较明显的类型可以不用声明,如果多次使用并一直被改变则需要声明类型,不然会经常提示报错;而且默认大可以兼容小; 下面来看一个TypeScript中内置的一个比较复杂的类型:ReturnType,表示方法返回值类型。

// 源码声明:
type ReturnType<T extends (...args:any[]) => any> = T extends (...args:any[])=> infer R ? R : any;

// 声明一个方法
const doSomething = (a: number)=>{
    return {
        a,
        b: 'hello world'
    }
}
// 获取doSomething方法的返回值类型
type newType = ReturnType<typeof doSomething>;

(...args:any[]) => any 通用方法类型:

T extends (...args:any[]) => any 泛型T是通用方法的子集,也就是也是个方法;

T extends (...args:any[]) 这里是方法的参数

infer R ? R : any; 方法的返回值。infer引入一个待推断的类型,这里代指方法声明的返回值类型