模式匹配-讓你TS類型體操水平暴增的套路
Typescript 支持泛型,也叫類型參數(shù),可以對類型參數(shù)做一系列運算之后返回新的類型,這就是類型編程。
因為類型編程實現(xiàn)一些邏輯還是有難度的,所以被戲稱為類型體操。
社區(qū)有用 Typescript 類型實現(xiàn) Lisp 解釋器、實現(xiàn)象棋等案例的(知乎可以搜到),這足夠說明了 Typescript 類型可以實現(xiàn)各種復雜邏輯。
那 Typescript 類型體操這么難,有沒有什么快速掌握的方式呢?
確實有,我總結了一些套路,可以快速提升 ts 類型體操水平。比如今天要講的套路--模式匹配。
Typescript 類型的模式匹配
我們知道,字符串可以和正則做模式匹配,找到匹配的部分,提取子組,之后可以用 $1,$2 等引用匹配的子組。
Typescript 的類型也同樣可以做模式匹配。
比如,提取 Promise
我們通過 extends 對傳入的類型參數(shù) T 做模式匹配,其中 value 部分是需要提取的,通過 infer 類聲明一個局部變量 R 來保存,如果匹配,就返回匹配到的 R,否則就返回 never 代表沒匹配到。
這就是 Typescript 類型的模式匹配。
小結一下: Typescript 類型的模式匹配是通過 extends 對類型參數(shù)做匹配,結果保存到通過 infer 聲明的局部類型變量里,如果匹配就能從該局部變量里拿到提取出的類型。
這個模式匹配的套路有多有用呢?我們來看下在數(shù)組、字符串、函數(shù)等類型里的應用。
數(shù)組類型的模式匹配
pop
pop 是去掉最后一個元素,可以通過模式匹配來實現(xiàn):
我們通過模式匹配取出最后一個元素的類型和前面的元素的類型,分別用 infer 放入不同的變量里,然后構造一個新的數(shù)組類型返回。
shift
同樣,shift 是去掉最開始的元素,也是類似的匹配方式來實現(xiàn):
字符串類型的模式匹配
trim
trim 是去掉前后的空格、制表符、換行符,那么就通過模式匹配取出后面的字符,通過 infer 放入新的變量返回就行。
先實現(xiàn) TrimLeft:
如果匹配就繼續(xù)遞歸 TrimLeft,直到前面沒有空白字符。
再實現(xiàn) TrimRight:
然后兩者結合,就是 Trim:
replace
replace 是替換字符串中的一部分,可以通過模式匹配取出這段字符串前后的子串,通過 infer 放入不同的變量,然后和替換后的部分組成新字符串。
函數(shù)類型的模式匹配
參數(shù)類型
取出參數(shù)的類型是通過模式匹配拿到參數(shù)部分,放入 infer 聲明的變量里返回。
返回值類型
取出返回值類型也是通過模式匹配拿到返回值部分,放入 infer 聲明的類型變量里返回。
總結
類型編程是對類型參數(shù)(泛型)做一系列運算之后返回新的類型,也叫類型體操。
類型體操可以實現(xiàn)很多復雜的邏輯,學習起來也有一定的難度,但是掌握一些套路之后也能快速掌握。
這些套路里面最常用的就是模式匹配了,類似字符串匹配和提取子串,類型也可以通過 extends 對類型參數(shù)做匹配,把需要提取的部分保存到通過 infer 聲明的局部類型變量里。
類型參數(shù)的模式匹配的套路在字符串類型、數(shù)組類型、函數(shù)類型等都有大量的應用,掌握這一個套路可以提升一大截類型體操的水平。