一、什么是泛型

泛型就是解决类、接口、函数中不确定类型的数据支持。

二、接口和抽象类的区别

  • 不同类之间的公有的属性或者方法,可以抽象成一个接口(interface)。
  • 抽象类是提供一个基础类供其他类继承,抽象类不能被实例化。抽象类中的方法必须在子类中实现。
  • 一个类可以继承一个抽象类或者类(extends),但可以实现多个接口(implements)。
  • 抽象类也可以实现接口。

    三、接口和类型别名的区别

  • 类型别名不能被继承(extends)和实现(implements),如果一个类型需要被继承或者实现的话要用接口的形式。

  • 当我们需要使用联合类型后者元组的时候,类型别名更合适。

    四、typeof、keyof、ReturnType、infer、InstanceType的用途

    1、typeof操作符

    在typescript中typeof关键字可以获取一个变量或者对象的类型。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. const sum: Person = { name: 'wz', age: 18 };
    6. type Sum = typeof sum; // type Sum = Person
    typeof操作符出了可以获取对象的结构类型之外,还可以获取函数对象的类型。
    1. function toArray(x: number): Array<number> {
    2. return [x];
    3. }
    4. type Func = typeof toArray; // (x: number) => number[]

    2、keyof操作符

    在typescript中keyof关键字用来查询索引类型的操作符。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. type PersonKey = keyof Person; // type PersonKey = name | age
    在自定义的时候可以用in操作符去批量定义类型中的属性。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. type PartPerson = { // 该方法将一个接口中的属性都变成可选属性
    6. [Key in keyof Person]?: Person[key]
    7. }

    3、ReturnType操作符

    在typescript中ReturnType关键字是用来获取函数的返回类型的操作符。
    infer关键字表示在extends条件语句中待推断的类型变量。
    可以通ReturnType的方式获取函数返回值的类型。
    1. const getUserInfor = () => ({ name: 'wz', age: 18 });
    2. type UserInfo = ReturnType<typeof getUserInfo>;
    3. const user: UserInfo = { name: 'wz', age: 18 };
    4. // 实质上UserInfo的类型可以推断到的类型为:
    5. interface UserInfo {
    6. name: string,
    7. age: number
    8. }
    下方是ReturnType的实现方式:
    1. type ReturnType<T extends (...args: any[]) => any>
    2. = T extends (...args: any[]) => infer R ? R : any;

    4、InstanceType操作符

    在typescript中InstanceType获取构造函数类型的实例类型。使用方式为InstanceType,可以获取通过构造函数创建出的对象的类型。下方是实现方式:
    1. type Construtor = new (...args: any[]) => any;
    2. type ConstrutorParams<T extends Construtor> = T extends new (...args: infer P) => any ? P : any;
    3. type InstanceType<T extends Construtor> = T extends new (...args: any[]) => infer R ? R : any;
    4. class Person {
    5. name: string
    6. construtor(name) {
    7. this.name = name;
    8. }
    9. getName() {
    10. return this.name;
    11. }
    12. }
    13. // 获取构造函数的参数
    14. type constructorParams = ConstrutorParams<typeof Person>;
    15. type Instance = InstanceType<Person>;
    16. const instance: Instance = { name: 'wz', getName() {} };

    五、Exclude、Extract、NonNullable的用途以及实现

    1、Exclude关键字

    在typescript中Exclude关键字是用来从一个T类型中剔除U类型的。从T可分配的类型中排除U。
    1. type E = Exclude<string | number, string>;
    2. const e: E = 10; // E: number
    3. // 以下为实现过程
    4. type Exclude = T extends U ? never : T;

    2、Extract关键字

    在typescript中Extract关键字是用来从一个T类型中拿到U类型的。从T可分配的类型中提取U。
    1. type E = Extract<string | number, string>;
    2. const e: E = 'wz'; // E: string
    3. // 以下为实现过程
    4. type Extract = T extends U ? T : never;

    3、NonNullable关键字

    在typescript中NonNullable关键字是用来从一个T类型中排除null和undefined。
    1. type E = NonNullable<string | number | null | undefined>;
    2. const e: E = 10 // E: string | number
    3. // 以下是实现过程
    4. type NonNullable = T extends null | undefined ? never : T;

    六、Partial、Required、ReadOnly、Pick、Record、Omit的用途以及实现

    1、Partial关键字

    在typescript中Partial关键字可以用来将传入的属性变成可选的。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. type person = Partial<Person>;
    6. const a: person = {}; // 正确不会报错
    7. // 以下是实现方式
    8. type Partial<T> = { [P in keyof T]?: T[P] };

    2、Required关键字

    在typescript中Required关键字可以将传入的属性中的可选项变成必选项,这里用-?修饰符来实现。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. const p: Required<Person> = { name: 'wz' };
    6. // 以下是实现方式
    7. type Required<T> = { [P in keyof T]-?: T[P] };

    3、ReadOnly关键字

    在typescript中ReadOnly关键字可以将传入的属性都加上readonly修饰符。
    1. // 以下是实现方式
    2. type ReadOnly<T> = { readonly [P in keyof T]: T[P] };

    4、Pick关键字

    在typescript中Pick关键字可以帮助我们从传入的属性集合中摘取某一项返回。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. type person = Pick<Person, 'name'> // person = { name: string }
    6. // 以下是实现方法
    7. type Pick<T, K extends keyof T> = { [P in K]: T[P] };

    5、Record关键字

    在typescript中Record关键字可以将一个类型的所有属性映射到另一个类型,并返回一个新的类型。
    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. type p = Record<string | number, Person> // p = { [x: string]: Person, [x: number]: Person };
    6. // 以下是实现方法
    7. type Record<K extends keyof any, T> = { [P in K]: T };

    6、Omit关键字

    在typescript中Omit关键字可以帮助我们排除传入属性集合中的某些属性。
    1. interface Person {
    2. name: string
    3. age: number
    4. id: number
    5. }
    6. type p = Omit<Person, 'age'> // p = { name: string, id: number }
    7. // 以下是实现方法
    8. type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof K, T>>;