前置知识
typescript类型遵循规则:先显式指定;无显式指定则进行推断。
进行推断的条件:
- 具有初始化值的变量
- 有默认值的函数参数
- 函数返回的类型
如果不满足推断条件,就会显示:具有隐式any类型。例如:变量没有初始化值;函数参数既没有显示指定,又没有默认值。
什么是泛型
泛型是类型参数化,用来约束类型成员之间的关系:
- 函数参数和返回值
- 类或接口成员和方法之间的关系
基础使用
约束函数参数类型
- 使用定义泛型参数,使用:T对函数参数进行指定
function fn<T>(params:T) {
return params
}
- 也可以对返回值进行一些指定(虽然可以推断出来):
function fn<T>(params:T):T {
return params
}
- 可以对函数参数的成员或者属性进行指定:
function fn<T>(params:T[]) {
return params
}
// 调用
const arr = fn(['1',1]) // arr:string|number[]
调用方法
- 既可以自动推断,又可以手动指定
fn(10) // 自动推断
fn<string>('hello') // 手动指定
- 指定两个或者多个
function fn<T, K>(a:T, b:k):T {
console.log(b)
return a
}
fn<string,number>('hello', 1)
动手实践
现在给定一个场景:手动实现lodash库里面的pick函数,用法示例如下:
import * as _ from 'lodash'
const obj = {
a : 1,
b : 'sdfa',
c : [1,2,'1']
}
const newObj = _.pick(obj, 'a','c')
console.log(newObj)
obj和newObj的类型分别为:
const obj: {
a: number;
b: string;
c: (string | number)[];
}
const newObj: Pick<{
a: number;
b: string;
c: (string | number)[];
}, "a" | "c">
代码:
const pick = function<T, K extends keyof T>(obj: T, pickArr: K[]) {
return pickArr.reduce((newObj, key) => {
if(Object.keys(obj).includes(key as string)) {
newObj[key] = obj[key]
return newObj
}
}, {} as Pick<T, K>)
}
const newObj = pick(obj, ['a', 'c'])