泛型是指在定义函数,接口或类时,不预先指定具体的类型,而是在运行时再指定类型的能力,这使得代码更加灵活可重用
泛型函数的类型参数通过尖括号‘<>’来定义,通常放在函数名称后面,这样,函数可以在不同的调用场景中适配不同的数据类型。
实例:
function identity<T>(arg: T): T {
return arg;
}
在这个例子中,'T’是一个类型参数,函数’identyty’的参数和返回值都使用了这个类型参数。这意味着可以用任意类型来调用这个函数
实例·
let result1 = identity<number>(42); // result1 的类型是 number
let result2 = identity<string>("Hello"); // result2 的类型是 string
这里‘identity’表示类型参数’T’被替换为‘number’,因此函数参数‘arg’必须是‘number’类型。同样地,‘identity’将’T’t替换成’string’
有时希望泛型函数不仅仅适用于任意类型,而是要对类型参数进行一定的约束。例如要求传入的类型必须具有某些属性或者方法
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length);
}
logLength("Hello"); // 字符串具有 length 属性
logLength([1, 2, 3]); // 数组具有 length 属性
在这个例子中,‘T extends HasLength’表示‘T’必须是一个具有‘length’属性的类型
大多用于基类的封装
class GenericClass<T> {
value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let instance = new GenericClass<number>(42);
console.log(instance.getValue()); // 输出 42
泛型接口
interface GenericInterface<T> {
value: T;
getValue(): T;
}
class GenericClass<T> implements GenericInterface<T> {
value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let instance = new GenericClass<string>("Hello");
console.log(instance.getValue()); // 输出 "Hello"
函数和类可以使用多个泛型参数,定义多个类型
function pair<A, B>(first: A, second: B): [A, B] {
return [first, second];
}
let result = pair<string, number>("hello", 42);
在这个例子中,函数‘pair’接收两个不同类型的参数,并返回一个包含这两个类型的元组