泛型
函数泛型
函数名后跟一个尖括号<>
,尖括号内部是动态类型参数(泛型)
1 2 3 4 5 6 7
| function yajue<T>(a:T,b:T,c:T):Array<T> { return [a,b,c] }
console.log(yajue<number>(1,1,4))
console.log(yajue("money","violence","sex"))
|
也可以同时使用多个泛型,只要在数量和使用方式上能对应即可
1 2 3 4
| function jueya<T,U>(a:T,b:U):Array<T|U> { return [a,b] } jueya<Boolean,number>(false,1)
|
还可以给泛型指定默认值
1 2 3 4 5
| function jueya<T = number>(a:T,b:T):Array<T> { return [a,b] }
|
泛型别名
在type中可以使用泛型
1 2 3 4 5 6 7
| type A<T> = string | number | T
let a:A<boolean> a = false a = "omg" a = 114514
|
泛型接口
泛型也可以用在接口上
1 2 3 4 5 6 7 8 9
| interface Data<T> { msg: T } let data1:Data<string> = { msg: "yjsp" } let data2:Data<number> = { msg: 114514 }
|
泛型类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Sub<T>{ attr: T[] = []; add (a:T):T[] { return [a] } } let s = new Sub<number>() s.attr = [1,2,3] s.add(123) let str = new Sub<string>() str.attr = ['1','2','3'] str.add('123')
|
泛型约束
期望在一个泛型的变量上面获取length参数
1 2 3
| function getLegnth<T>(arg:T) { return arg.length }
|
但是,有些数据类型是没有length属性,这时就可以使用泛型约束,此处约束T为具有length属性的类型
1 2 3 4 5 6 7 8 9
| interface Len { length:number } function getLegnth<T extends Len>(arg:T) { return arg.length } getLegnth<string>('123')
|
keyof约束对象
其中使用了TS泛型和泛型约束
- 首先,定义T类型,并使用extends关键字继承object类型的子类型
- 然后,使用keyof操作符获取T类型的所有键,它的返回类型是联合类型
- 最后,利用extends关键字约束K类型必须为keyof T联合类型的子类型
1 2 3 4 5 6 7 8
| function prop<T extends object, K extends keyof T>(obj: T, key: K) { return obj[key] } let o = { a: 1, b: 2, c: 3 } prop(o, 'a') prop(o, 'd')
|
type中也可以这么用
1 2 3 4 5 6 7 8 9 10 11
| type Options<T extends object> = { [Key in keyof T]?:T[Key] }
interface Data { name:string, age:number, sex:string }
type B = Options<Data>
|