# 七.泛型
前言
# 1.指定函数参数类型
- 单个泛型
const getArray = <T>(times: number, val: T): T[] => {
let result: T[] = [];
for (let i = 0; i < times; i++) {
result.push(val);
}
return result;
};
getArray(3, 3); // 3 => T => number
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 多个泛型
function swap<T, K>(tuple: [T, K]): [K, T] {
return [tuple[1], tuple[0]];
}
console.log(swap(["a", "b"]));
1
2
3
4
2
3
4
# 2.函数标注的方式
- 类型别名
type TArray = <T, K>(tuple: [T, K]) => [K, T];
const getArray: TArray = <T, K>(tuple: [T, K]): [K, T] => {
return [tuple[1], tuple[0]];
};
1
2
3
4
2
3
4
可以使用类型别名,但是类型别名不能被继承和实现。一般联合类型可以使用类型别名来声明
- 接口
interface TArray {
<T,K>(typle:[T,K]:[K,T])
}
const getArray:TArray = <T,K>(tuple:[T,K]):[K,T] => {
return [tuple[1],tuple[0]]
}
1
2
3
4
5
6
2
3
4
5
6
能使用 interface 尽量使用 interface
# 3.泛型接口使用
interface ISum<T> {
//这里的T是使用接口的时候传入
<U>(a: T, b: T): U; //这里的U是调用函数的时候传入
}
let sum: ISum<number> = (a: number, b: number) => {
return 3 as any;
};
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4.默认泛型
interface T2<T = string> {
name: T;
}
type T22 = T2;
let name1: T22 = { name: "ab" };
1
2
3
4
5
2
3
4
5
可以指定泛型的默认类型,方便使用
# 5.类中的泛型
- 创建实例时提供类型
class MyArray<T> {
// T=> number
arr: T[] = [];
add(num: T) {
this.arr.push(num);
}
getMaxNum(): T {
let arr = this.arr;
let max = arr[0];
for (let i = 1; i < arr.length; i++) {
let current = arr[i];
current > max ? (max = current) : null;
}
}
}
let myArr = new MyArray<number>();
myArr.add(3);
myArr.add(1);
myArr.add(2);
console.log(myArr.getMaxNum());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 校验构造函数类型
const createClass = <T>(clazz: new (name: string, age: number) => T): T => {
return new clazz(name, age);
};
createClass<Person2>(Person2);
1
2
3
4
2
3
4
# 6.泛型约束
- 泛型必须包含某些属性
interface IWithLength {
length: number;
}
function getLen<T extends IWithLength>(val: T) {
return val.length;
}
getLen("hello");
1
2
3
4
5
6
7
2
3
4
5
6
7
const sum = <T extends number>(a: T, b: T): T => {
return (a + b) as T;
};
let r = sum<number>(1, 2);
1
2
3
4
2
3
4
- 返回泛型中指定属性
const getVal = <T, K extends keyof T>(obj: T, key: K): T[K] => {
return obj[key];
};
1
2
3
2
3