携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
很多初学者在学习TypeScirpt这门语言都非常的吃了,学习了基本的接口、泛型、联合类型、元组等等一系列关于TypeScript知识。
但是在实际开发中去定义类型又非常不熟练,并且又有一种约束的感觉。总的来说对开发体验感极差从而导致对TypeScript这一门语言产生厌恶或者恐惧,从而 any 一把梭。
实际上,学习TypeScript并非一件容易的事,它是一个类型世界。我自己在初学TypeScirpt时也是产生这种恐惧的感觉,并没有给我的开发带来便利的感觉。到后面用多了才明白它的好。
TypeScript 工具类型
接下来主要是介绍一下 TypeScript 提供给我们的一些工具类型。
在文章中TypeScript要想玩的6,实用工具类型必须知(一)、 TypeScript要想玩的6,实用工具类型必须知(三)已经介绍过了十种实用工具类型,接下来就继续介绍最后的一些工具类型。
实现源码:
type CustomOmitType<T, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P];
};
ConstructorParameters<Type>
ConstructorParameters<Type> 获取类构造函数的参数的类型
先看看研究如何去对类的静态、动态部分进行类型约束
参考一下官方文档的讲解 官方文档
// 对类的静态部分 构造函数、静态变量、静态方法等进行约束
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
currentTime: Date;
}
// 对类想实例部分进行约束
interface ClockInterface {
tick(): void;
}
// 实现类接口对类的静态部分、实例部分约束写法:
const Clock: ClockConstructor = class Clock implements ClockInterface {
constructor(h: number, m: number) {}
static currentTime: Date = new Date();
tick() {
console.log("beep beep");
}
};
let clock = new Clock(12, 17);
// TS自带全局接口
// interface ErrorConstructor {
// new(message?: string): Error;
// (message?: string): Error;
// readonly prototype: Error;
// }
type TestConstructorParametersType = ConstructorParameters<ErrorConstructor>;
// 转换为如下类型
type TestConstructorParametersType = [message?: string | undefined]
实现源码:
type CustomConstructorParametersType<
T extends abstract new (...args: any) => any
> = T extends abstract new (...args: infer P) => any ? P : never;
ReturnType<Type>
ReturnType<Type> 构造一个返回函数类型T的返回值的类型
declare function f1(): { a: number; b: string };
type TestReturnType = ReturnType<typeof f1>;
// 转换为如下类型
type TestReturnType = {
a: number;
b: string;
}
实现源码:
type CustomReturnType<T extends () => any> = T extends () => infer X
? X
: never;
InstanceType<Type>
InstanceType<Type> 返回 Type类 的实例部分的类型
// 对类的静态部分 构造函数、静态变量、静态方法等进行约束
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
currentTime: Date;
}
// 对类想实例部分进行约束
interface ClockInterface {
tick(): void;
}
// 实现类接口对类的静态部分、实例部分约束写法:
const Clock: ClockConstructor = class Clock implements ClockInterface {
constructor(h: number, m: number) {}
static currentTime: Date = new Date();
tick() {
console.log("beep beep");
}
};
type TestCustomInstanceType = InstanceType<typeof Clock>;
// 转换为如下类型
type TestCustomInstanceType = ClockInterface
实现源码:
type CustomInstanceType<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: any) => infer X ? X : never;
ThisParameterType<Type>
ThisParameterType<Type> 返回函数Type中参数名为 this的类型,如果没有则返回unknown
function toHex(this: number) {
return this.toString(16);
}
type TestThisParameterType = ThisParameterType<typeof toHex>;
// 转换为如下类型
type TestThisParameterType = number
实现源码:
type CustomThisParameterType<T extends (this: any, ...args: any) => any> =
T extends (this: infer X, ...args: any) => any ? X : unknown;
OmitThisParameter<Type>
OmitThisParameter<Type> 将函数Type中函数名为 this的类型移除,返回一个新的函数类型
function toHex(this: number) {
return this.toString(16);
}
type TestOmitThisParameter = OmitThisParameter<typeof toHex>;
// 转换为如下类型
type TestOmitThisParameter = () => string
实现源码:
type CustomOmitThisParameter<T extends (this: any, ...args: any) => any> =
T extends (this: any, ...args: infer A) => infer X
? (...args: A) => X
: never;
ThisType<Type>
ThisType<Type> 构造一个对象中的所有函数的this指向类型,它只能在对象内的类型声明时使用
查看官方源码可以看到它的实现方式:interface ThisType<T> { } 其实我也还不理解它的具体使用场景
type Point = {
x: number;
y: number;
moveBy: (dx: number, dy: number) => void;
} & ThisType<{ message: string }>;
let p: Point = {
x: 10,
y: 20,
moveBy(dx, dy) {
this; // {message:string}
},
};
四个内置字符串工具类型
Uppercase<StringType>将字符串字母全部大写Lowercase<StringType>将字符串字母全部小写Capitalize<StringType>将字符串首字母都大写Uncapitalize<StringType>将字符串首字母都小写
总结
TypeScript的实用工具类型到这里就全部介绍完成。其中有一些工具类型在平时开发当中使用的频率还是蛮高的。所以还是需要不断积累学习在开发中使用这些工具类型。
另外在GitHub有一个开源项目是关于TS类型体操 的,在那里可以提高我们的TS类型声明。