-
在TypeScript(TS)中,泛型是一种非常有用的特性,它允许我们创建可重用的组件,这些组件可以处理多种类型的数据而不是单一的数据类型。
-
以下是一些在TypeScript中常用的泛型:
- 泛型函数:
function fun<T>(arg: T): T { return arg; } - 泛型接口:
interface DemoInterface<T> { (arg: T): T; } - 泛型类:
class DemoClass<T> { zeroValue: T; add: (x: T, y: T) => T; } - 泛型约束:
interface DemoInterface { length: number; } function demoFun<T extends DemoInterface>(arg: T): T { // 现在知道它有length属性,所以没有更多的错误 console.log(arg.length); return arg; } - 泛型工具类型:
-
泛型工具类型的使用场景非常广泛,它们提高了代码的灵活性和可重用性,同时保持了类型安全性。
-
在实际开发中,根据具体的需求,你可以组合使用这些工具类型来创建更复杂的类型。
-
Partial<T>:将T的所有属性转换为可选的。type Partial<T> = { [P in keyof T]?: T[P]; };- 当你想要将一个对象的所有属性变为可选的,例如,在更新一个对象的部分属性时。
interface Todo { title: string; description: string; } function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) { return { ...todo, ...fieldsToUpdate }; } const todo1 = { title: "organize desk", description: "clear clutter", }; updateTodo(todo1, { description: "throw out trash" }); -
Readonly<T>:将T的所有属性转换为只读的。type Readonly<T> = { readonly [P in keyof T]: T[P]; };- 当你想要确保对象在创建后不会被修改,例如,创建一个不可变的数据结构。
interface Config { readonly host: string; } const config: Readonly<Config> = { host: "localhost", }; // 错误:不能分配给'host',因为它是一个只读属性。 // config.host = "example.com"; -
Pick<T, K>:从T中选择一组属性K来构造一个新的类型。type Pick<T, K extends keyof T> = { [P in K]: T[P]; };- 当你需要从一个类型中选取一组属性来构造一个新的类型,例如,从表单提交的数据中提取需要发送到后端的部分
interface User { id: number; name: string; email: string; } type UserWithoutId = Pick<User, "name" | "email">; function saveUserDetails(userDetails: UserWithoutId) { // 保存不带id的详细信息 } -
Record<K, T>:构造一个类型,其属性名的类型为K,属性值的类型为T。type Record<K extends keyof any, T> = { [P in K]: T; };- 当你想要创建一个对象类型,其键和值的类型都是确定的,例如,一个映射对象。
const namesById: Record<number, string> = { 1: "Alice", 2: "Bob", 3: "Charlie", }; function getNameById(id: number): string { return namesById[id]; } -
Exclude<T, U>:从T中排除那些可以赋值给U的类型(返回差集)。type Exclude<T, U> = T extends U ? never : T;- 当你想要从一个联合类型中排除某些类型,例如,从函数的参数类型中排除某些值。
type AvailableColors = "red" | "green" | "blue"; type ChosenColors = "red" | "blue"; // "green" 是唯一有效的值 const color: Exclude<AvailableColors, ChosenColors> = "green"; -
Extract<T, U>:提取T中可以赋值给U的那些类型(返回交集)。type Extract<T, U> = T extends U ? T : never;- 当你想要从一个联合类型中提取某些类型,例如,找到两个接口共有的属性。
interface FirstType { id: number; name: string; age: number; } interface SecondType { id: number; name: string; gender: string; } // CommonProperties 将为 "id" | "name" type CommonProperties = Extract<keyof FirstType, keyof SecondType>; -
NonNullable<T>:从T中排除null和undefined。type NonNullable<T> = T & {};- 当你想要从类型中排除
null和undefined,例如,在处理函数返回值时。
type Foo = string | number | null | undefined; type NonNullableFoo = NonNullable<Foo>; function assertNotNull<T>(value: T): NonNullable<T> { if (value === null || value === undefined) { throw new Error("值不能为 null 或 undefined"); } return value; } - 当你想要从类型中排除
-
-
泛型在TypeScript中非常强大,它们提供了一种方法来创建可重用的代码组件,同时还能保持类型安全。
-
通过使用泛型,可以编写更加灵活和可维护的代码。