运用泛型提升JavaScript,以类型安全方式操作数据
2023-12-08 04:05:28
泛型是TypeScript最强大的功能之一,它允许您创建可重用且灵活的代码。在本文中,我们将探讨如何使用泛型来创建可重用且灵活的代码。
什么是泛型?
泛型是一个占位符,允许您在代码中使用任何类型。例如,您可以定义一个名为List
的泛型,它可以存储任何类型的元素。
class List<T> {
private data: T[];
constructor(...items: T[]) {
this.data = items;
}
add(item: T) {
this.data.push(item);
}
get(index: number): T {
return this.data[index];
}
size(): number {
return this.data.length;
}
}
上面的代码定义了一个泛型类List
。该类可以存储任何类型的元素。您可以在实例化该类时指定元素的类型。例如,您可以创建一个存储字符串的List
如下:
const list = new List<string>("Hello", "World");
现在,您可以使用该列表就像使用任何其他JavaScript数组一样。
console.log(list.get(0)); // Hello
console.log(list.size()); // 2
泛型不仅可以用于类,还可以用于函数和接口。例如,您可以定义一个名为map
的泛型函数,它将一个数组中的每个元素映射到一个新值。
function map<T, U>(array: T[], f: (item: T) => U): U[] {
return array.map(f);
}
上面的代码定义了一个泛型函数map
。该函数将一个数组中的每个元素映射到一个新值。您可以使用该函数来将一个字符串数组映射到一个数字数组,如下所示:
const numbers = map(["1", "2", "3"], (item: string) => parseInt(item));
现在,numbers
变量将包含一个数字数组:[1, 2, 3]。
泛型的类型
泛型可以是任何类型,包括类、接口、函数和原始类型。例如,您可以定义一个名为Box
的泛型类,它可以存储任何类型的元素。
class Box<T> {
private data: T;
constructor(data: T) {
this.data = data;
}
get(): T {
return this.data;
}
}
上面的代码定义了一个泛型类Box
。该类可以存储任何类型的元素。您可以实例化该类并传入任何类型的元素。例如,您可以创建一个存储字符串的Box
如下:
const box = new Box("Hello World");
现在,您可以使用该box
变量就像使用任何其他JavaScript变量一样。
console.log(box.get()); // Hello World
泛型还可以用于接口。例如,您可以定义一个名为Printable
的泛型接口,它表示一个可打印的类型。
interface Printable<T> {
print(): T;
}
上面的代码定义了一个泛型接口Printable
。该接口表示一个可打印的类型。您可以创建任何类型的Printable
实现。例如,您可以创建一个打印字符串的Printable
实现,如下所示:
class StringPrintable implements Printable<string> {
private data: string;
constructor(data: string) {
this.data = data;
}
print(): string {
return this.data;
}
}
上面的代码定义了一个StringPrintable
类,它实现了Printable
接口。该类打印一个字符串。您可以实例化该类并打印一个字符串,如下所示:
const printable = new StringPrintable("Hello World");
console.log(printable.print()); // Hello World
泛型还可以用于函数。例如,您可以定义一个名为map
的泛型函数,它将一个数组中的每个元素映射到一个新值。
function map<T, U>(array: T[], f: (item: T) => U): U[] {
return array.map(f);
}
上面的代码定义了一个泛型函数map
。该函数将一个数组中的每个元素映射到一个新值。您可以使用该函数来将一个字符串数组映射到一个数字数组,如下所示:
const numbers = map(["1", "2", "3"], (item: string) => parseInt(item));
现在,numbers
变量将包含一个数字数组:[1, 2, 3]。
泛型的约束
泛型类型可以被约束为只能是某些类型的元素。例如,您可以定义一个名为List
的泛型类,它只能存储字符串元素。
class List<T extends string> {
private data: T[];
constructor(...items: T[]) {
this.data = items;
}
add(item: T) {
this.data.push(item);
}
get(index: number): T {
return this.data[index];
}
size(): number {
return this.data.length;
}
}
上面的代码定义了一个泛型类List
。该类只能存储字符串元素。您可以实例化该类并传入一个字符串数组。例如,您可以创建一个存储字符串的List
如下:
const list = new List<string>("Hello", "World");
现在,您可以使用该列表就像使用任何其他JavaScript数组一样。
console.log(list.get(0)); // Hello
console.log(list.size()); // 2
泛型约束还可以用于函数和接口。例如,您可以定义一个名为map
的泛型函数,它将一个数组中的每个元素映射到一个新值,并且该新值必须是字符串类型。
function map<T extends string, U extends string>(array: T[], f: (item: T) => U): U[] {
return array.map(f);
}
上面的代码定义了一个泛型函数map
。该函数将一个数组中的每个元素映射到一个新值,并且该新值必须是字符串类型。您可以使用该函数来将一个字符串数组映射到一个字符串数组,如下所示:
const numbers = map(["1", "2", "3"], (item: string) => item.toUpperCase());
现在,numbers
变量将包含一个字符串数组:["1", "2", "3"]。