返回
类型系统中的泛型化方略:从 TypeScript 学习泛型编程的精髓
前端
2023-09-23 08:17:48
基础必备知识
联合类型 vs 交叉类型
联合类型使用 “|”表示或的关系,满足其中的一个情况即可。
type User = {
name: string;
};
type Admin = {
name: string;
role: string;
};
type UserOrAdmin = User | Admin;
let userOrAdmin: UserOrAdmin = {
name: 'John',
};
// userOrAdmin 可以是 User 或 Admin 类型
console.log(userOrAdmin.name); // John
交叉类型使用“&”表示与的关系,必须满足所有情况。
type UserWithAdmin = User & Admin;
let userWithAdmin: UserWithAdmin = {
name: 'John',
role: 'admin',
};
// userWithAdmin 必须同时具有 User 和 Admin 的属性
console.log(userWithAdmin.name); // John
console.log(userWithAdmin.role); // admin
类型别名
类型别名可以让我们给一个类型起一个新的名字,使代码更加简洁和易读。
type StringOrNumber = string | number;
let stringOrNumber: StringOrNumber = 'Hello';
// stringOrNumber 可以是 string 或 number 类型
console.log(stringOrNumber); // Hello
类型参数
类型参数允许我们在定义函数或类时使用泛型类型。类型参数用尖括号 <> 表示,放在函数或类名的后面。
function identity<T>(value: T): T {
return value;
}
let numberIdentity: number = identity(10);
// numberIdentity 的类型是 number
console.log(numberIdentity); // 10
let stringIdentity: string = identity('Hello');
// stringIdentity 的类型是 string
console.log(stringIdentity); // Hello
约束
约束可以限制泛型类型的范围,确保泛型类型满足某些条件。约束使用 extends 表示。
function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
let name = getProperty({ name: 'John' }, 'name');
// name 的类型是 string
console.log(name); // John
推断
TypeScript 可以推断泛型类型的具体类型,这使得代码更加简洁和易于维护。
function swap<T>(a: T, b: T): [T, T] {
return [b, a];
}
let [first, second] = swap(1, 2);
// first 的类型是 number
console.log(first); // 2
// second 的类型是 number
console.log(second); // 1
案例
泛型编程在 TypeScript 中有很多应用场景,以下是一些常见的案例:
- 集合:泛型可以用于定义集合类型,如数组、链表、栈等。
- 算法:泛型可以用于定义算法,如排序、搜索、遍历等。
- 函数式编程:泛型可以用于定义高阶函数,如 map、filter、reduce 等。
- 组件:泛型可以用于定义可重用的组件,如 React 组件、Angular 组件等。
总结
泛型编程是 TypeScript 中一项强大的特性,它允许我们在代码中定义通用的类型,这些类型可以适用于不同类型的数据。泛型编程可以使代码更加简洁、易读和可维护。通过学习 TypeScript 中的泛型,我们可以理解泛型编程的精髓,并将其应用到我们的代码中。