TypeScript 魔法工具类型:让你的代码焕发奇迹! 🪄✨

83 阅读4分钟

TypeScript (TS) 作为现代前端开发的必备神器,其丰富的工具类型为开发者提供了极大的便利和强大的类型保障。这些工具类型不仅能够让我们的代码更加简洁优雅,还能让类型操作变得轻而易举,如同魔法般妙不可言。接下来,让我们一起探秘这些TypeScript中令人惊叹的工具类型吧! 🚀✨

常用工具类型 🌟

1. Partial<Type>:将类型属性全部变为可选

你是否曾想过,可以让一个对象的所有属性瞬间变为可选?Partial正是你的魔法棒! 🪄

type Person = { name: string; age: number; };
实现:
type MyPartial<T> = { [key in keyof T]?: T[key] }
使用:
type PartialPerson = Partial<Person>;

// 结果:{ name?: string; age?: number; }

只需一行代码,所有属性皆可选,让代码灵活到令人窒息! 😲

2. Readonly<Type>:让所有属性变为只读

想要确保对象的属性不被篡改?Readonly让你的代码固若金汤! 🔒

实现:
type MyReadonly<T> = { readonly [key in keyof T]: T[key] }
使用:
type ReadonlyPerson = Readonly<Person>;

// 结果:{ readonly name: string; readonly age: number; }

只需一行代码,万物皆不可变,守护数据的完美工具。 🛡️

3. Record<Keys, Type>:构建指定键值对类型

你可以随意构建一个拥有指定键和值类型的对象,Record让你如同造物主般创建万物! 🌍

type Names = '张三' | '李四' | '王二';
实现:
type MyRecode<K extends keyof any, T> = { [P in K]: T }
使用:
type RecordPerson = Record<Names, Person>;

// 结果:{ '张三': Person; '李四': Person; '王二': Person; }

赋予对象新生命,掌控键和值的完美结合! 🧬

4. Pick<Type, Keys>:选择你想要的属性

是否只想获取一个对象的部分属性?Pick为你裁剪最适合的部分! ✂️

实现:
type MyPick<T, K extends keyof T> = { [P in K]: T[P] }
使用:
type PickPerson = Pick<Person, 'name'>;

// 结果:{ name: string; }

精准提取,完美契合,你的需求由你做主! 🎯

5. Omit<Type, Keys>:排除你不需要的属性

想要剔除不必要的属性?Omit为你扫清一切障碍! 🚫

1.
*!<约束为T和any都行>
type MyOmit<T, K extends T *> = {
     [P in keyof T as P extends K ? never : P]: T[P]
}
2. 结合其他工具类型实现
type MyOmit<T, K extends any> = Pick<TExclude<keyof T, K>>
使用:
type OmitPerson = Omit<Person, 'name'>;

// 结果:{ age: number; }

舍弃繁杂,简洁高效,让你的类型纯净如初! 🌿

6. Exclude<Type, ExcludedUnion>:排除不需要的类型

轻松排除不想要的类型,Exclude让你精简到极致! ✨

实现:
type MyExclude<T, U> = T extends U ? never : T
使用:
type ExcludedType = Exclude<'name' | 'age' | 'sex', 'name' | 'sex'>;

// 结果:'age'

精准排除,留下最需要的部分,代码从此简约而不简单! 🌟

7. Extract<Type, Union>:提取想要的类型

想要提取某些类型?Extract让你如同大海捞针般轻松自如! 🌊

实现:
和Exclude正好相反
type MyExclude<T, U> = T extends U ? T : never
使用:
type ExtractedType = Extract<'name' | 'age' | 'sex', 'name' | 'sex'>;

// 结果:'name' | 'sex'

精挑细选,精准提取,你想要的类型一网打尽! 🎣

8. NonNullable<Type>:去除null和undefined

再也不怕null和undefined的困扰,NonNullable让你的类型纯粹无比! 🧼

实现:
1.
type MyNonNullable<T> = T & {}
T & {} 是做一个交叉类型空对象会将T这个联合类型中的nullundefined去除
2.
type MyNonNullable<T> = T extends null | undefined ? never : T
使用:
type NonNullableType = NonNullable<Person | boolean | undefined | null | number>;

// 结果:Person | boolean | number

告别null和undefined,让你的代码纯净如水! 💧

9. Parameters<Type>:获取函数参数类型

轻松获取函数的参数类型,Parameters让你洞悉一切! 🔍

实现:
type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never
使用:
function foo(a: number, person: {name: string}) {}
type FooParameters = Parameters<typeof foo>;

// 结果:[number, {name: string;}]

窥探函数的内在奥秘,参数类型尽在掌握! 🔮

10. ConstructorParameters<Type>:获取构造函数参数类型

了解构造函数的参数类型,ConstructorParameters让你尽在掌握! 📐

实现:
type MyConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never
使用:
class Person {
  constructor(a: number, p: {name: string}) {}
}
type PersonConstructorParameters = ConstructorParameters<typeof Person>;

// 结果:[number, {name: string;}]

构造函数的神秘面纱,为你揭开! 🕵️‍♂️

11. ReturnType<Type>:获取函数返回值类型

函数的返回值类型一目了然,ReturnType为你揭晓真相! 📬

实现:
type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer P ? P : never
使用:
function cat() { return {name: '', age: 2}; }
type CatReturnType = ReturnType<typeof cat>;

// 结果:{name: string; age: number;}

返回值类型无所遁形,代码更具可读性! 📖

12. InstanceType<Type>:获取类的实例类型

轻松获取类的实例类型,InstanceType让你全面掌控! 🕹️

实现:
type MyInstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer P ? P : never
使用:
class P {
  functionName: string;
  constructor(a: number, b: boolean) {}
  sayHello() {}
}
type PInstanceType = InstanceType<typeof P>;

// 结果:P

类的实例尽在掌握,代码更为简洁清晰! 🧩

13. Required<Type>:将所有属性变为必选

再也不用担心可选属性带来的困扰,Required让一切都变得明确! ✅

实现:
type MyRequired<T> = { [P in keyof T]-?: T[P] }
-?取消可选
使用:
type OptionalPerson = { name?: string };
type RequiredPerson = Required<OptionalPerson>;

// 结果:{ name: string }

所有属性必选,让你的代码更加可靠! 🛠️

结语

TypeScript 的这些工具类型,犹如开发者的秘密武器,让代码编写变得如此轻松愉快。掌握它们,你将如虎添翼,在代码的世界中游刃有余,打造出更健壮、更灵活的应用。现在就动手试试这些工具类型吧,让你的代码焕发出无穷魅力! 🌈💫