定义泛型函数
- 为了确保传入的类型与返回的类型相同,使用
类型变量T表示传入参数和返回值的类型
function identity<T>(arg: T): T {
return arg
}
let output = identity<string>("myString");
let output = identity("myString");
使用泛型变量
- 明确表示传入的参数为T类型的数组,确保参数有
.length这个属性
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
function loggingIdentity<T>(arg: Array<T>): Array<T> {
console.log(arg.length);
return arg;
}
泛型类型
- 泛型函数的类型,只需要将类型参数写在最前面,跟函数声明一样
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = identity;
let myIdentity2: <U>(arg: U) => U = identity;
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: {<T>(arg: T): T} = identity;
interface GenericIdentityFn {
<T>(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn = identity;
- 把泛型参数当作整个接口的一个参数,指定
GenericIdentityFn的类型,这样接口里的其它成员也能知道这个参数的类型
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; };
GenericNumber类的使用是十分直观的,并且你可能已经注意到了,没有什么去限制它只能使用number类型。 也可以使用字符串或其它更复杂的类型
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };
console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));
泛型约束
- 定义一个接口来描述约束条件。 创建一个包含
.length属性的接口,使用这个接口和extends关键字来实现约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
loggingIdentity("good")
loggingIdentity(123)
loggingIdentity({length: 10, value: 3})
loggingIdentity({})
loggingIdentity([])
在泛型约束中使用类型参数
- 声明一个类型参数,且它被另一个类型参数所约束。 比如,现在我们想要用属性名从对象里获取这个属性。 并且我们想要确保这个属性存在于对象 obj上,因此我们需要在这两个类型之间使用约束
function getProperty(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a");
getProperty(x, "m");