泛型
更新时间: 2023-03-02 11:16:25
# 泛型
泛型可以理解为类型的形参,T是一个标识符,可以自定义,T表示某种类型
function fn1<T,G>(n:T,m:G):Array<T|G> {
return [n,m]
}
fn1<number,string>(100,"1")
fn1<boolean,number>(true,1)
fn1<'hello','world'>('hello','world')
1
2
3
4
5
6
2
3
4
5
6
# 泛型定义类型别名
type StrOrNum = string|number
//type ObjType = {name:string,getName:() => string}
type ObjType<N,G=number> = {name:N,getName:() => G}
let obj:ObjType<StrOrNum> = {
name:"",
getName(){
return 1
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 泛型定义接口
// 泛型 - 接口
// interface PersonItf {
// name:string,
// getName:() => string
// }
// 可以设置默认的类型,在使用的时候就可以省略不传
interface PersonItf<N,G=string> {
name:N,
getName:() => G
}
let obj2:PersonItf<StrOrNum,StrOrNum> = {
name:"",
getName:() => {
return ""
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 对象字面量泛型
let foo:{<T>(arg:T):T}
foo = function<T>(arg:T):T {
return arg
}
foo(123)
1
2
3
4
5
6
7
2
3
4
5
6
7
# 泛型约束
我们期望在一个泛型的变量上面,获取其length参数,但是,有的数据类型是没有length属性的,于是我们就可以使用类型约束,约束其为具有length属性的类型
interface Len {
length:number
}
function getlength<T extends Len>(arg:T) {
return arg.length
}
getLength<string>('123')
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 使用keyof约束对象
其中使用了TS泛型和泛型约束。首先定义了T类型并使用extends关键字继承object类型的子类型,然后使用keyof操作符获取T类型的所有键,它的返回 类型是联合 类型,最后利用extends关键字约束 K类型必须为keyof T联合类型的子类型
function prop<T,K extends keyof T>(obj:T,key:K) {
return obj[key]
}
let o = {a:1,b:2,c:3}
prop(o,'a')
//prop(0,'d') 报错
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 泛型类
声明方法跟函数类似名称后面定义<类型>
使用的时候确定类型new Sub<number>()
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')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14