🤪🤪TS高级用法(四)

648 阅读2分钟

如今,越来越多的项目使用了TypeScript进行编写,我们都知道TypeScriptJavaScript的超集,它为JavaScript提供了强大的类型和语法增强功能,能在项目开发的过程中大大减少错误的产生。而TypeScript也内置了很多的工具类型,接下来,我将带着大家学习TypeScript中的工具类型。

本文中为系列文章的第四篇

InstanceType

InstanceType用于获取一个类的实例的类型。

栗子

class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
​
type PersonType=InstanceType<typeof Person>;
// type PersonType = Person
​
​
type AT =InstanceType<any>
// type AT = any// type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any

分析

判断传入的T类型是否为一个抽象类,通过inter推断类返回的参数

type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any

ThisParameterType

ThisParameterType用于提取函数的this的参数类型,传入的类型必须是一个函数类型。

栗子

import Person from "./ConstructorParameters";
​
function f1(this:Person){
    console.log(this);
}
​
type TT=ThisParameterType<typeof f1>
// type TT = Person

分析

推断T类型是否为一个函数,接着推断函数中的this类型。

type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown

OmitThisParameter

同上面的Omit类似,OmitThisParameter用于移除类型中的this类型。

栗子

function foo(this: number) {
  console.log(this);
}
​
const fooType: OmitThisParameter<typeof foo> = foo.call(1);

分析

这里传入了ThisParameterType,先得到T函数的this类型,判断是否为一致,后续推断出AR类型。

type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T

ThisType

ThisType用于在字面量对象中指定this

只有在 --noImplicitThis 的选项下才有效

栗子

// 简单的栗子
interface data {
  count: number;
  increase:()=>void
}
​
// 复杂一点的栗子
type ObjectDescriptor<D, M> = {
  data?: D;
  methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
};
​
function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
  let data: object = desc.data || {};
  let methods: object = desc.methods || {};
  return { ...data, ...methods } as D & M;
}
​
let obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
      this.x += dx; // Strongly typed this
      this.y += dy; // Strongly typed this
    },
  },
});
​
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);