最近使用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