在ts中,泛型允许在定义函数、接口类和类型别名时,不预先指定具体类型,而是在使用时指定。以达到增加代码复用性和代码安全性的目的。下面举几个例子。
泛型函数
泛型用于函数示例,它返回传入的任意类型的参数;
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("hello"); //类型是string
let output2 = identity<number>(100); //类型是string
泛型接口
泛型用于接口上,定义通用的接口。
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型类
泛型类示例。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {return x + y;};
let stringNumeric = new GenricNumber<number>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) {return x + y;};
泛型约束
如果我们希望泛型不是任意类型,而是满足条件的特定类型,可以使用泛型约束。
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); //知道它有length属性,因此不会报错
return arg;
}
loggingIdentity({length: 10, value: 3}); //正确
使用多个类型参数的泛型
泛型可以有多个类型参数
function mapObject<K, V, T>(obj: Record<K, V>, mapFn: (value: V) => T): Record<K, T> {
let result: Record<any, T> = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = mapFn(obj[key]);
}
}
return result;
}
let original = { a: 1, b: 2, c: 3 };
let mapped = mapObject(original, (value) => value.toString());
// mapped 的类型是 { a: string, b: string, c: string }
泛型提供了创建可重用组件的方式,同时保持类型的完整性和灵活性。在TS中广泛用于库、框架和应用程序的编写。