持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
内置工具
TypeScript的目的是为JavaScript添加一套类型校验系统,因为JavaScript本身的灵活性,也让TypeScript类型系统不得不增加更复杂的功能以适配JavaScript的灵活性
也就是说TypeScript是一种可以支持类型编程的类型系统,同时为了方便我们使用TypeScript, TS提供了大量的内置工具以简化我们对应的类型操作
Partial<Type>
用于构造一个Type下面的所有属性都设置为可选的类型
使用
interface IUser {
name: string;
age: number;
}
type User = Partial<IUser>
/*
type User = {
name?: string | undefined;
age?: number | undefined;
}
*/
实现
interface IUser {
name: string;
age: number
}
type MyPartial<T> = {
[K in keyof T]?: T[K]
}
type User = MyPartial<IUser>
Required<Type>
用于构造一个Type下面的所有属性全都设置为必填的类型,这个工具类型跟 Partial 相反
使用
interface IUser {
nam?: string;
age?: number;
}
type User = Required<IUser>
/*
=>
type User = {
nam: string;
age: number;
}
*/
实现
interface IUser {
nam?: string;
age?: number;
}
type MyRequired<T> = {
[K in keyof T]-?: T[K]
}
type User = MyRequired<IUser>
Readonly<Type>
用于构造一个Type下面的所有属性全都设置为只读的类型,意味着这个类型的所有的属性全都不可以重新赋值
使用
interface IUser {
nam: string;
age: number;
}
type User = Readonly<IUser>
/*
=>
type User = {
readonly nam: string;
readonly age: number;
}
*/
实现
interface IUser {
nam: string;
age: number;
}
type MyReadonly<T> = {
readonly [K in keyof T]: T[K]
}
type User = MyReadonly<IUser>
Record<Keys, Type>
使用
interface IUser {
nam: string;
age: number;
}
type Names = 'Alex' | 'Steven' | 'Jhon'
type User = Record<Names, IUser>
/*
=>
type User = {
Alex: IUser;
Steven: IUser;
Jhon: IUser;
}
*/
实现
interface IUser {
nam: string;
age: number;
}
type Names = 'Alex' | 'Steven' | 'Jhon'
// keyof any -> 返回所有可以作为索引值的类型组成的联合类型
// keyof any --> number | string | symbol
// K extends keyof any 可以确保K是字符串类型或数值类型或symbol类型或他们的联合类型
// 也就意味着K 可以在映射类型中通过in关键字进行遍历
type MyRecord<K extends keyof any, T> = {
// P in 联合类型 -- 取出联合类型中的每一项值并使用
// keyof 对象 -- 得到对象key组成的联合类型
[P in K]: T
}
type User = MyRecord<Names, IUser>
Pick<Type, Keys>
用于构造一个类型,它是从Type类型里面挑了一些属性Keys
使用
interface IUser {
name: string;
age: number;
address: string;
}
type Keys = 'name' | 'age'
type User = Pick<IUser, Keys>
/*
=>
type User = {
name: string;
age: number;
}
*/
实现
interface IUser {
name: string;
age: number;
address: string;
}
type Keys = 'name' | 'age'
// 在这里并不需要约束T 一定是对象类型 即T extends {}
// 因为只有对象才可以执行keyof
// 所以如果T不是对象,那么在执行MyPick的时候 就会报错
type MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}
type User = MyPick<IUser, Keys>
Omit<Type, Keys>
用于构造一个类型,它是从Type类型里面过滤了一些属性Keys
使用
interface IUser {
name: string;
age: number;
address: string;
}
type Keys = 'address'
type User = Omit<IUser, Keys>
/*
=>
type User = {
name: string;
age: number;
}
*/
实现
interface IUser {
name: string;
age: number;
address: string;
}
type Keys = 'address'
type MyOmit<T, K> = {
[P in keyof T as P extends K ? never: P]: T[P]
}
type User = MyOmit<IUser, Keys>
Exclude<UnionType, ExcludedMembers>
用于构造一个类型,它是从UnionType联合类型里面排除了所有可以赋给ExcludedMembers的类型
使用
type Key = 'name' | 'age' | 'address'
type ExcludeKey = Exclude<Key, 'address'> // => typeof ExcludeKey -> 'name' | 'age
实现
type Key = 'name' | 'age' | 'address'
// 在MyExclude中T传入的值是联合类型
// 所以这里会使用到条件类型判断中的联合类型扩散
// 当生成的联合类型中有never的时候, never类型会被自动移除
type MyExclude<T, U> = T extends U ? never : T
type ExcludeKey = MyExclude<Key, 'address'>
Extract<Type, Union>
用于构造一个类型,它是从Type类型里面提取了所有可以赋给Union的类型
使用
type Key = 'name' | 'age' | 'address'
type ExtractKey = Extract<Key, 'address'> // typeof ExtractKey -> 'address'
实现
type Key = 'name' | 'age' | 'address'
type MyExtract<T, U> = T extends U ? T : never;
type ExtractKey = MyExtract<Key, 'address'>
NonNullable<Type>
用于构造一个类型,这个类型从Type中排除了所有的null、undefined的类型
使用
type Key = 'name' | 'age' | null | undefined
type Result = NonNullable<Key>
// type Result = "name" | "age"
实现
type Key = 'name' | 'age' | null | undefined
type MyNonNullable<T> = T extends null | undefined ? never : T;
type Result = MyNonNullable<Key>
ReturnType<Type>
用于构造一个含有Type函数的返回值的类型
使用
function foo(num: number) {
return num + ''
}
type Result = ReturnType<typeof foo>
// type Result = string
实现
function foo(num: number) {
return num + ''
}
type MyReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : never
type Result = MyReturnType<typeof foo>
InstanceType<Type>
用于构造一个由所有Type的构造函数的实例类型组成的类型
使用
class Dog {}
class Cat {}
function factoryFn<T extends new (...args: any[]) => any>(ctor: T, ...params: any[]): InstanceType<T> {
return new ctor(...params)
}
const instance1 = factoryFn(Dog)
const instance2 = factoryFn(Cat)
实现
class Dog {}
class Cat {}
type MyInstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : never
function factoryFn<T extends new (...args: any[]) => any>(ctor: T, ...params: any[]): MyInstanceType<T> {
return new ctor(...params)
}
const instance1 = factoryFn(Dog)
const instance2 = factoryFn(Cat)
ThisParameterType<Type>
传入一个函数,并取出传入的this所对应的类型
使用
function foo(this: string) {
console.log('foo fun')
}
type ThisParameter = ThisParameterType<typeof foo>
// type ThisParameter = string
实现
function foo(this: string) {
console.log('foo fun')
}
type MyThisParameterType<T extends (this: any, ...args: any[]) => any> = T extends (this: infer P, ...args: any[]) => any ? P : never
type ThisParameter = MyThisParameterType<typeof foo>
OmitThisParameter<Type>
移除函数中的this类型参数
使用
function foo(this: string, name: string, age: number) {
console.log('foo fun')
}
type ThisParameter = OmitThisParameter<typeof foo>
// type ThisParameter = (name: string, age: number) => void
实现
function foo(this: string, name: string, age: number) {
console.log('foo fun')
}
// 如果不存在this,那么ThisParameterType<T>的返回值 就是unknown
// 在进行...args: infer A 类型推断的时候,this的类型会被自动抹除
type MyOmitThisParameter<T extends (...args: any[]) => any> = unknown extends ThisParameterType<T> ? T :
T extends (...args: infer A) => infer R ? (...args: A) => R : unknown
type ThisParameter = MyOmitThisParameter<typeof foo>
ThisType<Type>
这个类型不返回一个转换过的类型,它被用作标记一个上下文的this类型
使用
interface IState {
name: string
age: number
}
interface IStore {
state: IState
printName: () => void
printAge: () => void
}
// ThisType<IState> -> 对象store中的所有this的类型都是IState
const store: IStore & ThisType<IState> = {
state: {
name: 'Klaus',
age: 23
},
printName() {
console.log(this.name)
},
printAge() {
console.log(this.age)
}
}
store.printName.call(store.state)
store.printAge.call(store.state)
Awaited<Type>
这种类型是为了模拟像async函数中的await或Promises上的.then()方法这样的操作
Awaited<Type>会递归的对Promise进行解包操作
使用
type A = Awaited<Promise<string>> // typeof A -> string
type B = Awaited<Promise<Promise<number>>> // typeof B -> number
type C = Awaited<boolean | Promise<number>> // typeof C -> boolean | number
Parameters<Type>
返回由函数参数类型组成的元组类型
使用
type T0 = Parameters<() => string> // type T0 = []
type T1 = Parameters<(s: string | number) => void> // type T1 = [s: string | number]
实现
type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer A) => any ? A : never
type T0 = MyParameters<() => string>
type T1 = MyParameters<(s: string | number) => void>
ConstructorParameters<Type>
返回构造函数的参数所组成的元组类型
使用
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
type T1 = ConstructorParameters<typeof Person>
// type T1 = [name: string, age: number]
实现
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
type MyConstructorParameters<T extends new(...args: any[]) => void> = T extends new(...args: infer R) => void ? R : never
type T1 = MyConstructorParameters<typeof Person>