乐趣区

「深入探讀 TypeScript 中的泛型:從基礎到進階應用」

深入探讀 TypeScript 中的泛型:从基础到进阶应用

TypeScript 是 JavaScript 的超集,它为 JavaScript 添加了类型系统和其他高级特性。泛型是 TypeScript 中的一项强大特性,它允许我们定义可以处理多种类型的函数和类。在本文中,我们将深入探讨 TypeScript 中的泛型,从基础到进阶应用。

  1. 泛型的基本概念

泛型是一种类型参数化的技术,它允许我们定义可以处理多种类型的函数和类。在 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

  1. 泛型约束

在某些情况下,我们可能希望限制泛型类型的范围,以便更好地控制函数或类的行为。这就是泛型约束的作用。

例如,下面的函数是一个简单的泛型函数,它只能处理具有 length 属性的数组:

typescript
function slice<T>(arr: T[], start: number, end: number): T[] {
return arr.slice(start, end);
}

在这个例子中,我们定义了一个名为 slice 的函数,它有三个类型参数 Tstartend。这个函数接受一个类型为 T 的数组 arr,并返回一个新的数组,其中包含从 startend 的元素。

我们可以使用这个函数来处理具有 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"]

  1. 泛型类型推断

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 可以自动推断 result1result2result3 的类型,因为我们已经传递了具体的值。

  1. 泛型类和接口

我们可以使用泛型来定义类和接口,这可以帮助我们更好地控制类和接口的行为。

例如,下面的类是一个简单的泛型类,它可以处理具有 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,并提供了一些方法来操作数组,例如 getsetpushslice

我们可以使用这个类来处理具有 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”]
“`

  1. 泛型的进阶应用

泛型可以帮助我们更好地处理复杂的数据结构和场景,例如:

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 = T[] & { length: number};

退出移动版