最近使用TypeScript写了一个项目,过程当中不断感觉到TypeScript的魅力,如今来分享几个业务中关于泛型的场景数组
TS内置了一个Partial
类型,用于把一个类型的成员属性设置为成可选模式,例如编辑器
type Person = { name: string; age: number; }
Person
类型中有两个成员属性,若是咱们要把这个类型赋予变量tom
,那tom
必须拥有name
和age
两个属性函数
let tom:Person = { name: 'tom', age: 20 };
如今咱们要让Person
的两个属性都变为可选,能够使用Partial
类型进行转换学习
type PartialPerson = Partial<Person>; let partialPerson: PartialPerson = { name: 'tom' };
这时PartialPerson
的name
和age
属性都已经变为可选的了,可是若是咱们在Person
中再加一点东西this
type Person = { name: string; age: number; contact: { email: string; phone: number; wechat: string; } }
如今咱们加入了一个contact
属性值是一个对象,若是咱们想把contact
里面的属性也变为可选Partial
就不灵了spa
能够看到Partial
是把contact
变成了可选而不是里面的属性,插个题外话一般的作法是为contact
另外建立一个类型,若是是这样的话Partial
就能够用了,可是咱们不使用这种方法,咱们先来看看TS是怎么定义Partial
的code
/** * Make all properties in T optional */ type Partial<T> = { [P in keyof T]?: T[P]; };
很容易理解关键点是在?:
上,如今咱们改造一下对象
type DeepPartial<T> = { [P in keyof T]?: T[P] extends Object ? DeepPartial<T[P]> : T[P]; }
能够看到改造的DeepPartial
跟Partial
差异在把直接赋值T[P]
换成了T[P] extends Object ? DeepPartial<T[P]> : T[P]
, 即判断T的属性P的类型是不是Object
而后进行再次DeepPartial
或者返回T[P]
的类型ip
这时编译器就不会再提示错误了文档
array_column
函数在PHP中有一个array_column
函数,用于在数组中提取一列的内容,用JavaScript表现就是
function array_column(arr, key) { return arr.map(item => item[key]) }
假如如今有一个persons
数组
type Person = { name: string; age: number; } let persons: Person[] = [];
咱们须要提取数组中的name
属性,能够很方便的使用Array.map
方法提取,可是若是又有别的数组须要提取,咱们能够实现一个更优雅的array_column
函数
function array_column<T, K extends keyof T>(input: T[], key: K) { return input.map(item => item[key]) }
如今咱们使用这个函数提取persons
数组
能够看到当咱们输入persons
时,编辑器已经推断出了key
的类型,再来一个animals
数组
在刚开始学习TS的时候看官方文档有一个Proxy的例子,只给出了类型声明但却没有给出实现,当时花了很多时间琢磨,如今来实现它
class Proxy<T>{ constructor(private data: T) { } get<K extends keyof T>(key: K) { return this.data[key] } set<K extends keyof T, V extends T[K]>(key: K, value: V) { this.data[key] = value; } }
能够看到Proxy类提供了getter
方法get
和setter
方法set
,如今咱们基于上面的Person
类型建立一个Proxy实例
let person: Person = { name: 'tom', age: 18 }; let proxy = new Proxy(person);
如今咱们来看看调用get
方法
能够看到编辑器也推断出了参数key
的类型,再来看看set
方法
和get
方法同样,编辑器也推断出了参数key
的类型,同时也推断出了参数value
的类型为string