一些在TypeScript上費過時間的地方總結(jié)
記錄一些自己在ts上費過時間的地方。
(先吐個槽:stackoverflow是真的啥都有,百度是真的沒法用)
坑
as斷言的兼容性誤解,如"a" as "b"這種代碼是不會報錯的。
interface和type的不一致行為(初遇還以為自己寫錯類型,一臉懵逼的):
type Type = { key: "value" } interface Interface { key: "value" } type 似乎沒差別都是true = Type extends Interface ? Type extends Interface ? true : false : false type 坑點 = { [key: string]: 坑點 } | string type 測試<T> = T extends 坑點 ? true : false type 這個是true = 測試<Type> type 這個是false = 測試<Interface>
github上官方有說明,是故意留這么個坑的。說是因為interface可擴展(同名自動合并),所以不便檢測。
用泛型實現(xiàn)函數(shù)重載的效果時,在函數(shù)的實現(xiàn)中,會因泛型不具備具體約束,導(dǎo)致經(jīng)常需要使用as強制斷言。
//差不多這意思,下面的代碼懶得實際測了🙃 //fns是個函數(shù)索引表,TFns是索引表的const類型 function 重載失敗<T extends keyof TFns>(fn:T, params: Parameters<fns[T]>){ fns[fn](...params)//在實現(xiàn)中聯(lián)合類型不會縮小,所以會報錯 //錯誤應(yīng)該像是 不能將方法1的參數(shù)傳給方法2 這種 } //但外部使用時,符合類型的語義也沒啥事
擴展運算符并不符合直觀感受: [...string[], number]這種類型在使用時是符合閱讀時的直覺的(要求數(shù)組末尾是number元素),但是[...string[], null, ...object[], number]這種不行,不會按順序來也不會報錯。新版ts加了禁止連續(xù)解構(gòu)的規(guī)則,這種類型直接不讓寫了。
其實這里有解決辦法,但是寫出來的類型簡直沒法看(幾十行,包含大量extends充當類型的if判斷),就不貼了 下面貼代碼:
//需要的類型:[...number[], "middle-element", ...boolean[]] //上面的寫法是無效的,只是示意下面的類型代碼是干什么用的(實現(xiàn)上面示意的類型約束) type Elem = number | boolean | "middle-element"; type Last<T extends any[]> = T extends [infer _] ? never : T extends [...infer _, infer Tl] ? Tl : never type HandleEmpty<T extends any[], Data> = T['length'] extends 0 ? never : Data type Validation<Params extends any[], Cache extends Elem[] = []> = Params extends [] ? Cache['length'] extends 0 ? never : Cache : Params extends [infer Fst, ...infer Rest] ? Cache extends [] ? Fst extends number ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>> : never : Fst extends number ? Last<Cache> extends number ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>> : never : Fst extends "middle-element" ? Last<Cache> extends number ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>> : never : "middle-element" extends Cache[number] ? Fst extends boolean ? Validation<Rest, [...Cache, Fst]> : never : never : never type IsNever<T> = [T] extends [never] ? true : false; function check< Params extends Elem[], IsValid extends Validation<Params> >(...arr: IsNever<IsValid> extends true ? [never] : [...Params]) { return arr } const 正常 = check(1, 'middle-element', false) const 報錯 = check(false, "middle-element", 2)
進階操作
對象名重映射:
//{ "new-a":any; "new-b":any } type 重映射 = { [K in "a" | "b" as `new-${K}`]: any }
聯(lián)合類型的拆分:用infer關(guān)鍵字可以實現(xiàn)對聯(lián)合類型的拆分。
//"a1"|"b2" type 拆分成功<_Keys = keyof { a: 1, b: 2 }> = _Keys extends infer K ? `${Extract<K, string>}${{ a: 1, b: 2 }[Extract<K, _Keys>]}` : never //注意:(截止ts4.4.4)直接`keyof Obj extends infer K`無法分割聯(lián)合類型,原因不明(懶得查😁)。 //結(jié)果是"a1"|"a2"|"b1"|"b2" type 拆分失敗 = keyof { a: 1, b: 2 } extends infer K ? `${Extract<K, string>}${{ a: 1, b: 2 }[Extract<K, "a" | "b">]}` : never
元組類型:
- 實際(非類型)參數(shù)有時候需要通過as const明確定義為元組類型。
- 元組類型可以通過元組["length"]獲取準確的長度,而不是number。
- 元組類型在通過泛型參數(shù)使用時,有時候需要通過加個[]|寫成元組 extends []|any[]這種方式來避免被解析為普通的不定長數(shù)組類型。
遞歸類型:用...infer More可以實現(xiàn)對數(shù)組類型的遞歸。
type 轉(zhuǎn)換器<T> = T extends string ? "str" : null //進去是個[string,number,string],出來就會是["str",null,"str"] type 遞歸< 輸入源 extends any[], 內(nèi)部的類型緩存 extends any[] = [] > = 輸入源 extends [any, ...infer 剩余元素] ? 遞歸<剩余元素, [...內(nèi)部的類型緩存, 轉(zhuǎn)換器<輸入源[0]>]> : 輸入源
零碎
- &可以代替extends對type使用,interface除了可以合并同名的類型,其它的沒啥差別了。
- ts具有豐富的內(nèi)建類型,挑幾個例子:
- ReturnType<函數(shù)類型>,獲取函數(shù)類型的返回值的類型。
- Uncapitalize<字符串>,將輸入的字符串類型的首字母鎖定為小寫(其它還有首字母大寫、全小寫、全大寫)。
新手建議去官網(wǎng)翻文檔。
入了ts坑后,可以沒事關(guān)注下版本更新帶來的新特性(玩法)。
總結(jié)
到此這篇關(guān)于在TypeScript上費過時間的地方總結(jié)的文章就介紹到這了,更多相關(guān)ts費時間的地方內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用 Chrome Dev Tools 進行頁面性能分析的步驟說明(前端性能優(yōu)化)
這篇文章主要介紹了利用 Chrome Dev Tools 進行頁面性能分析的步驟說明(前端性能優(yōu)化),本文給大家介紹的非常想詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02JS如何設(shè)置cookie有效期為當天24點并彈出歡迎登陸界面
這篇文章主要介紹了JS如何設(shè)置cookie有效期為當天24點并彈出歡迎登陸界面的代碼,代碼比較簡單,好理解,需要的朋友可以參考下2016-08-08JavaScript高級程序設(shè)計 客戶端存儲學(xué)習(xí)筆記
JavaScript高級程序設(shè)計 客戶端存儲學(xué)習(xí)筆記,在客戶端用于存儲會話信息2011-09-09JS PHP字符串截取函數(shù)實現(xiàn)原理解析
這篇文章主要介紹了JS PHP字符串截取函數(shù)實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08