泛型变量
function identity<T>(arg: T): T {
return arg
}
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length)
return arg
}
泛型函数 loggingIdentity,接收类型参数 T 和参数 arg,arg是元素类型是 T 的数组,并返回元素类型是T 的数组。
泛型类型
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<number> = identity
当我们使用 GenericIdentityFn 的时候,还得传入一个类型参数来指定泛型类型(这里是:number),锁定了之后代码里使用的类型。
泛型类
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
}
泛型约束
interface Lengthwise {
length: number
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length) // OK
return arg
}
定义一个接口来描述约束条件,创建一个包含 .length 属性的接口,使用这个接口和 extends 关键字来实现约束.我们需要传入符合约束类型的值,必须包含必须的属性。
在泛型约束中使用类型参数
声明一个类型参数,且它被另一个类型参数所约束。
比如,现在我们想要用属性名从对象里获取这个属性。 并且我们想要确保这个属性存在于对象 obj 上,因此我们需要在这两个类型之间使用约束。
function getProperty<T, K extends keyof T> (obj: T, key: K ) {
return obj[key]
}
let x = {a: 1, b: 2, c: 3, d: 4}
getProperty(x, 'a') // okay
getProperty(x, 'm') // error