如今,越来越多的项目使用了TypeScript进行编写,我们都知道TypeScript是JavaScript的超集,它为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类型,判断是否为一致,后续推断出A和R类型。
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);