泛型(Generics)
可以在 数组、类 或 方法 中 限制类型
在数组中使用泛型
作用:
- 限制放数据的类型
不推荐写法
Array<Object> 中的 <> 部分,就是泛型写法
const students:Array<Object> = [
{
firstName:"李",
lastName:"雷"
},
{
name:"韩梅梅"
},
{
name:"张三",
age:20
},
]
for(let item of students){
console.log(item.firstName) // 这里报错
}
执行 tsc 泛型.ts 报错:
20 console.log(item.firstName)
~~~~~~~~~
Found 1 error in 泛型.ts:20
因为数组中,不是每个元素都有 firstName 属性
正确写法
定义接口
interface IPerson{
firstName: string
lastName: string
}
定义接口数组:
const students:Array<IPerson> = [
{
firstName:"李",
lastName:"雷"
},
{
firstName:"韩",
lastName:"梅梅"
},
{
firstName:"张",
lastName:"三"
},
]
在方法中使用泛型
格式
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){
}
有些时候,函数返回值的类型与参数类型是相关的。
// 取出数组的第一个元素,并返回
function getFirst(arr) {
return arr[0];
}
上面示例中,函数 getFirst() 总是返回参数 数组的第一个成员。参数数组是什么类型,返回值就是什么类型。
不推荐写法
这个函数的类型声明只能写成下面这样。
function f(arr: any[]): any {
return arr[0];
}
上面的类型声明,就反映不出参数与返回值之间的类型关系。
推荐写法
function getFirst<T>(arr: T[]): T {
return arr[0];
}
上面示例中,函数 getFirst() 的函数名后面尖括号的部分<T>,就是类型参数,参数要放在一对尖括号(<>)里面。本例只有一个类型参数 T,可以将其理解为类型声明需要的变量,需要在调用时传入具体的参数类型。
上例的函数 getFirst() 的参数类型是 T[] ,返回值类型是 T,就清楚地表示了两者之间的关系。比如,输入的参数类型是 number[],那么 T 的值就是 number,因此返回值类型也是 number。
函数调用时,需要提供类型参数。
getFirst<number>([1, 2, 3]);
上面示例中,调用函数 getFirst() 时,需要在函数名后面使用尖括号,给出类型参数T的值,本例是 <number>。
不过为了方便,函数调用时,往往省略不写类型参数的值,让 TypeScript 自己推断。
getFirst([1, 2, 3]);
上面示例中,TypeScript 会从实际参数 [1, 2, 3],推断出类型参数 T 的值为 number。
注意:有些复杂的使用场景,TypeScript 可能推断不出类型参数的值,这时就必须显式给出了
参考:
https://typescript.p6p.net/typescript-tutorial/generics.html