TypeScript学习——泛型
1.基本概念
泛型是一种传递类型的方式,是一种类型占位符,这种类型占位符告诉我们的(function、class或interface)我们在调用它时想要使用什么类型
const obj = {name: 'zhangSan',age: 18
}
function getValue<T,k extends keyof T>(obj: T,key: K):T[K] {return T[K]
}
getValue(obj,'name') // zhangSan
- 常用的泛型变量
T
:代表Type,在定义泛型时通常用作第一个类型变量名。K
:表示对象中的键类型V
:表示对象中的值类型E
:表示元素类型
2.泛型的基本使用
2.1 处理函数参数,统一输入和输出的类型
// 处理单个参数
function fn1<T>(arg:T):T {return arg
}fn1(123) // 123
fn1('zhangSan') // ‘zhangSan’// 处理多个参数
function fn2<T, U>(arg1: T,arg2: U)[T,U] {return [arg1, arg2]
}fn2(123,'zhangSan') // [123,'zhangSan']
我们在使用可以有两种方式指定类型
- 定义要使用的类型
// 这里指定了 T 的类型为 string
fn1<string>('zhangSan') // 'zhangSan'
- TS 类型推断,自动导出类型
// 这里没有指定 T 的类型,但是 TS 可以通过实参的类型(string)推到出 T 的类型为 string
fn1('zhangSan') // 'zhangSan'
使用 type
定义函数类型
type fn = <T>(arg: T) => T
const text: fn = function getObjValue(arg) {return arg
}
使用 interface
定义函数类型
interface Fn<T> {(arg: T) : T
}
2.2 泛型参数默认类型
语法:<T = default type>
// 使用 type 定义了 fn 函数,fn 函数的泛型默认是 number
type fn<T = number> = (arg: T) => T
2.3 泛型约束
- 约束函数参数类型
// 定义一个函数打印参数的 length
function printLnegth<T>(arg:T) {console.log(arg.length) // 这样写会报错,因为泛型 T 并没有 length 属性
}
这时可以通过 interface 来约束泛型
interface LengthProps {length: number
}function printLnegth<T extends LengthProps>(arg:T) {console.log(arg.length)
}
其中<T extends LengthProps>
,让泛型继承了接口 LengthProps
,使得泛型T
具有了 length
属性,从而使得函数参数具有了 length
属性
- 约束接口
interface KeyValue<T, U> {key: T,value: U
}const k1: KeyValue<number, string> = {key: 123, value: 'zhangSan'}
cosnt k2: KeyValue<string,number> = {key: 'zhangSan', value: 123}
- 约束数组
// 之前定义数组
const arr1: number[] = [1,2,3]// 通过泛型约束数组
const arr2: Array<number> = [1,2,3]
3. 小结
泛型
指的是在定义函数、接口或者类的时候,不预先指定具体的类型,而是在使用的时候在指定类型。泛型
中的 T
就像一个占位符、或者说一个变量,在使用的时候可以把定义的类型像参数一样传入,它可以原封不动地输出。