「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
泛型
基本使用
// 泛型变量的定义在函数名后边,参数类别的前边
const getArr = <T>(value: T, num = 5): T[] => {
return new Array(num).fill(value)
}
// 在实际调用的时候,我们可以显示的传入泛型变量所代表的值
getArr<number>(5)
// 如果我们不显示确定对应泛型变量的值
// 那么TypeScript的类型检测系统会自动根据我们所传入的value属性的值来确定对应泛型变量的类型
getArr('Klaus') // 此时泛型变量T的类型是 string
// 我们也可以同时使用多个泛型变量
function getTuple<T, U>(val1: T, val2: U) {
return [val1, val2]
}
在函数中使用泛型
type Sum = <T>(value: T, num?: number) => T[]
// 虽然在实际定义函数的时候, value的类型是any
// 但是在函数的类型中,value的类型是泛型T
// 所以实际value所对应的类型会取决于实际传入的实参的类型,而不会是any
const sum: Sum = (value: any, num = 5) => {
return new Array(num).fill(value)
}
sum('abc') // type value = string
sum(2) // type value = number
在别名中使用
type Sum = <T>(value: T, num?: number) => T[]
在接口中使用
// 此时泛型变量T 只能在函数这个粒度上进行使用
interface sum {
<T>(value: T, num?: number): T[]
}
// 我们也可以将泛型变量提升到整个接口范围内
// 这样所有在接口内部定义的内容都可以使用该泛型变量
interface sum<T> {
<T>(value: T, num?: number): T[]
count: T
}
泛型约束
默认情况下,泛型变量的类型是不被限制的,也就是说默认情况下泛型变量的类型都是any类型
但是很多时候,我们需要给泛型变量添加上对应的类型约束,以限制可以传入的泛型变量的类型
此时就可以使用泛型约束
// 使用extends关键字来对泛型变量进行约束
// T extends { length: number } 表示的是 传入的泛型变量的类型必须是具有length属性的值
function getLength<T extends { length: number }> {
return T.length
}
function getValue<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
const obj = {
a: 'aa',
b: 'bb'
}
// keyof v 获取的是索引类型 对应的是v中所有key的联合 在这里就是 'a' | 'b'
// valueof v 获取的也是索引类型 对应的是v中所有值的联合 在这里就是 'aa' | 'bb'
getValue(obj, 'a')