在定义函数,接口或者类的时候,不预先指定具体的类型,而是在使用的时候再指定类型的一种特性
上例子
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = []
for(let i = 0; i< length; i++) {
result[i] = value
}
return result
}
console.log(createArray<string>(3, 'x')) // [ 'x', 'x', 'x' ]
其实在不指定参数类型程序也可自动推导出类型,建议是指定
多个类型参数
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
console.log(swap([1, 'one'])) // [ 'one', 1 ]
泛型约束
在未知类型的时候,随意操作属性或者方法会出现问题,这种时候就需要对泛型进行约束
function aa<T> (arg: T): T {
console.log(arg.length)
return arg
}
// Property 'length' does not exist on type 'T'.
// 约束之后
interface Lengthwise {
length: number
}
function aa<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg
}
console.log(aa('7')) // 1 7
多个参数之间互相约束
function copyFields<T extends U, U>(target: T, source: U): T {
for (let key in source) {
target[key] = (<T>source)[key]
}
return target
}
let x = {a: 1, b: 2, c: 3, d: 4}
copyFields(x, {b: 10, d: 20})
console.log(x)
let y = {q: 1, w: 2}
copyFields(y, {t: 4, u: 5}) // 报错
泛型接口
interface CreateAaaryFunc<T> {
(length: number, value: T): Array<T>
}
let craeteArray: CreateAaaryFunc<any>
craeteArray = function<T>(length: number, value: T): Array<T> {
let result: T[] = []
for(let i = 0; i< length; i++) {
result[i] = value
}
return result
}
console.log(craeteArray(3 ,'x'))
console.log(craeteArray<number>(3 ,3)) // Expected 0 type arguments, but got 1
泛型类
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; };
泛型参数默认类型
function createArray<T = string>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}