共计 2900 个字符,预计需要花费 8 分钟才能阅读完成。
深入探讀 TypeScript 中的泛型:从基础到进阶应用
TypeScript 是 JavaScript 的超集,它为 JavaScript 添加了类型系统和其他高级特性。泛型是 TypeScript 中的一项强大特性,它允许我们定义可以处理多种类型的函数和类。在本文中,我们将深入探讨 TypeScript 中的泛型,从基础到进阶应用。
- 泛型的基本概念
泛型是一种类型参数化的技术,它允许我们定义可以处理多种类型的函数和类。在 TypeScript 中,我们可以使用尖括号(<>) 来定义泛型。
例如,下面的函数是一个简单的泛型函数,它可以处理任何类型的值:
typescript
function identity<T>(arg: T): T {
return arg;
}
在这个例子中,我们定义了一个名为 identity
的函数,它有一个类型参数 T
。这个函数接受一个类型为 T
的参数 arg
,并返回相同的类型 T
。
我们可以使用这个函数来处理任何类型的值,例如:
typescript
const result1 = identity(123); // number
const result2 = identity("hello"); // string
const result3 = identity({name: "John"}); // object
- 泛型约束
在某些情况下,我们可能希望限制泛型类型的范围,以便更好地控制函数或类的行为。这就是泛型约束的作用。
例如,下面的函数是一个简单的泛型函数,它只能处理具有 length
属性的数组:
typescript
function slice<T>(arr: T[], start: number, end: number): T[] {
return arr.slice(start, end);
}
在这个例子中,我们定义了一个名为 slice
的函数,它有三个类型参数 T
、start
和 end
。这个函数接受一个类型为 T
的数组 arr
,并返回一个新的数组,其中包含从 start
到 end
的元素。
我们可以使用这个函数来处理具有 length
属性的数组,例如:
typescript
const result1 = slice([1, 2, 3], 1, 3); // [2, 3]
const result2 = slice(["a", "b", "c"], 1, 3); // ["b", "c"]
const result3 = slice(["a", "b", "c"], 1); // ["b"]
- 泛型类型推断
TypeScript 可以自动推断泛型类型,这可以帮助我们更轻松地使用泛型。
例如,下面的函数是一个简单的泛型函数,它可以处理任何类型的值,并返回其类型:
typescript
function getType<T>(arg: T): T {
return arg;
}
在这个例子中,我们定义了一个名为 getType
的函数,它有一个类型参数 T
。这个函数接受一个类型为 T
的参数 arg
,并返回相同的类型 T
。
我们可以使用这个函数来获取任何类型的值的类型,例如:
typescript
const result1 = getType(123); // number
const result2 = getType("hello"); // string
const result3 = getType({name: "John"}); // object
TypeScript 可以自动推断 result1
、result2
和 result3
的类型,因为我们已经传递了具体的值。
- 泛型类和接口
我们可以使用泛型来定义类和接口,这可以帮助我们更好地控制类和接口的行为。
例如,下面的类是一个简单的泛型类,它可以处理具有 length
属性的数组:
“`typescript
class ArrayWrapper
private arr: T[];
constructor(arr: T[]) {
this.arr = arr;
}
get length(): number {
return this.arr.length;
}
get(index: number): T {
return this.arr[index];
}
set(index: number, value: T): void {
this.arr[index] = value;
}
push(value: T): void {
this.arr.push(value);
}
slice(start: number, end: number): T[] {
return this.arr.slice(start, end);
}
}
“`
在这个例子中,我们定义了一个名为 ArrayWrapper
的类,它有一个类型参数 T
。这个类有一个私有的数组属性 arr
,并提供了一些方法来操作数组,例如 get
、set
、push
和 slice
。
我们可以使用这个类来处理具有 length
属性的数组,例如:
“`typescript
const arr1 = [1, 2, 3];
const arr2 = [“a”, “b”, “c”];
const wrapper1 = new ArrayWrapper(arr1);
const wrapper2 = new ArrayWrapper(arr2);
console.log(wrapper1.length); // 3
console.log(wrapper2.length); // 3
console.log(wrapper1.get(1)); // 2
console.log(wrapper2.get(1)); // “b”
wrapper1.push(4);
wrapper2.push(“d”);
console.log(arr1); // [1, 2, 3, 4]
console.log(arr2); // [“a”, “b”, “c”, “d”]
console.log(wrapper1.slice(1, 3)); // [2, 3]
console.log(wrapper2.slice(1, 3)); // [“b”, “c”]
“`
- 泛型的进阶应用
泛型可以帮助我们更好地处理复杂的数据结构和场景,例如:
- 处理异步操作的返回值:我们可以使用泛型来定义异步操作的返回值类型,例如:
typescript
async function fetchData<T>(url: string): Promise<T> {
const response = await fetch(url);
const data = await response.json();
return data as T;
}
- 处理多个类型的值:我们可以使用泛型来定义处理多个类型的值的函数或类,例如:
typescript
function merge<T extends object, U extends object>(obj1: T, obj2: U): {[key: string]: any } {
const result: {[key: string]: any } = {};
for (const key in obj1) {
result[key] = obj1[key];
}
for (const key in obj2) {
result[key] = obj2[key];
}
return result;
}
- 处理类型的约束:我们可以使用泛型来定义类型的约束,例如:
“`typescript
type MyArray