Typescript?extends?關(guān)鍵字繼承類型約束及條件類型判斷實現(xiàn)示例解析
引言
最近團隊新增了一個 HC
,面試候選人的過程中,看他簡歷,履歷很牛逼,并且里面寫的精通 TypeScript
。
我想那我們就問一個很基礎(chǔ)的問題吧,你了解 Typscript
的 extends
關(guān)鍵字嗎?它都會在那幾個場景下使用?
結(jié)果很失望,即使在我寫出了 extends
的使用方式時,這位哥們還沒想起怎么用,只能含糊其辭。
我趕緊換了一個問題,避免太尷尬:你了解 ts
工具類型 Exclude
與 Omit
的使用嗎?及它們兩個的區(qū)別?
這哥們還是不會~
不出意外的一面就掛了,說這個事的原因是,現(xiàn)在經(jīng)濟下行、市場上是狼多肉少,大家一定要珍惜面試機會,實事求是,平時多積累、多梳理,戰(zhàn)時抓機會、少冷場啊。
好了下面說正事。
extends 關(guān)鍵字實現(xiàn)繼承
如果你有看過 TypeScript
官方文檔,起碼熟悉這兩個:
extends
關(guān)鍵字可以實現(xiàn)interface
類型的擴展,- 這個也是
interface
與type
類型別名實現(xiàn)擴展的區(qū)別之一,類型別名通過&
交叉類型來實現(xiàn)類型擴展
- 這個也是
extends
關(guān)鍵字可用于class
的繼承
比如定義個 Animal
接口
interface Animal { name: string } interface Person extends Animal { level: number } const person: Person = { name: 'Perter', level: 1 } interface Dog extends Animal { leg: number } const dog: Dog = { name: 'BaGong', leg: 4 }
如果使用 class
class Animal { move() { console.log("Moving along!"); } } class Person extends Animal { talk(info: string) { console.log(info) } } const person = new Person(); // Base class method person.move(); // Derived class method person.talk('hello world') class Dog extends Animal { woof(times: number) { for (let i = 0; i < times; i++) { console.log("woof!"); } } } const d = new Dog(); // Base class method d.move(); // Derived class method d.woof(3);
這種方式就是在踐行 extends
單詞的本意 擴展
。
extends 實現(xiàn)類型約束
很貼切的列子就是 Typescript
的工具類型 Pick
,可以通過從一個 類型中選取一組屬性集合來構(gòu)造一個新的類型。
接下來讓我們實現(xiàn)下:
type MyPick<T, Keys> = { [key in Keys]: T[key] // error: Type 'key' cannot be used to index type 'T'. }
如果你直接這么寫,ts
編譯器肯定是要報錯的。因為用戶傳入的屬性集合中很可能在 T
中不存在!
所以我們需要對屬性集合 Keys
進行約束,約束其必須為 T
的屬性集合子集。
type MyPick<T, Keys extends keyof T> = { [key in Keys]: T[key] } // 使用 interface Todo { title: string; description: string; completed: boolean; } type TodoPreview = MyPick<Todo, "title" | "completed">; const todo: TodoPreview = { title: "Clean room", completed: false, }; todo; // ok
這是第二種方式,對泛型參數(shù)進行約束。
extends 實現(xiàn)條件類型判斷
在 TypeScript
類型體操基礎(chǔ)動作中,有一種動作叫:條件類型,條件類型主要用于去判斷兩個類型之間的關(guān)系。
建議閱讀 類型體操基礎(chǔ)動作
比如工具類型 Exclude
的實現(xiàn),就是基于條件類型:
type MyExclude<T, Key> = T extends Key ? never : T
可以實現(xiàn)基于聯(lián)合類型 Key
,排除聯(lián)合類型 T
中匹配的類型。
type T0 = MyExclude<"a" | "b" | "c", "a">; // type T0 = "b" | "c" type T1 = MyExclude<"a" | "b" | "c", "a" | "b">; // type T1 = "c"
在多數(shù)工具類型中,都用到了這個特性,最常見的就是遞歸類型。遞歸三要素之一就是要有終止條件,而我們就可以通過 extends
實現(xiàn)終止條件的判斷。
比如
- 實現(xiàn)一個 DeepReadonly 工具類型,可以做到將對象類型的所有屬性轉(zhuǎn)為只讀:
type DeepReadonly<T> = keyof T extends never ? T : { readonly [Key in keyof T]: DeepReadonly<T[Key]> : T[Key] }
- 實現(xiàn)一個 TrimLeft ,可以實現(xiàn)移除字符串類型的左邊空格:
type Space = ' ' | '\n' | '\t' type TrimLeft<S extends string> = S extends `${Space}${infer R}` ? TrimLeft<R> : S type trimed = TrimLeft<' Hello World '> // expected to be 'Hello World '
- 實現(xiàn)一個 KebabCase 類型,可以實現(xiàn)對字符串類型的駝峰轉(zhuǎn)橫杠:
type KebabCase<T extends string> = T extends `${infer F}${infer R}` ? R extends Uncapitalize<R> ? `${Uncapitalize<F>}${KebabCase<R>}` : `${Uncapitalize<F>}-${KebabCase<R>}` : T; type FooBarBaz = KebabCase<"FooBarBaz">; const foobarbaz: FooBarBaz = "foo-bar-baz"; type DoNothing = KebabCase<"do-nothing">; const doNothing: DoNothing = "do-nothing";
是不是很有意思?
最后
恭喜你,通過短短幾分鐘,有進步了一丟丟。
參考
- TypeScript:https://www.typescriptlang.org/docs/handbook/2/everyday-types...
- DeepReadonly: https://github.com/type-challenges/type-challenges/blob/main/questions/00009-medium-deep-readonly/README.md
- TrimLeft: https://github.com/type-challenges/type-challenges/blob/main/questions/00106-medium-trimleft/README.md
- KebabCase:https://github.com/type-challenges/type-challenges/blob/main/questions/00612-medium-kebabcase/README.md
以上就是Typescript extends 關(guān)鍵字的三個妙用的詳細內(nèi)容,更多關(guān)于Typescript extends 關(guān)鍵字的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Typescript編碼規(guī)范ESLint和Prettier使用示例詳解
這篇文章主要介紹了Typescript編碼規(guī)范ESLint和Prettier使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09TypeScript逆變之條件推斷和泛型的應(yīng)用示例詳解
這篇文章主要為大家介紹了TypeScript逆變之條件推斷和泛型的應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09Typescript?extends?關(guān)鍵字繼承類型約束及條件類型判斷實現(xiàn)示例解析
這篇文章主要介紹了Typescript?extends?關(guān)鍵字繼承類型約束及條件類型判斷實現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08TypeScript快速學(xué)習(xí)入門基礎(chǔ)語法
TypeScript的基礎(chǔ)語法,包括變量聲明、復(fù)合類型(數(shù)組和對象)、條件控制(if-else和switch)、循環(huán)(for和while)、函數(shù)(基礎(chǔ)和箭頭函數(shù),以及可選參數(shù))、面向?qū)ο筇匦裕杜e、接口、繼承)以及模塊開發(fā)中的導(dǎo)出和導(dǎo)入2024-07-07TypeScript與JavaScript的區(qū)別分析
TypeScript可以使用JavaScript中的所有代碼和編程概念,TypeScript是為了使JavaScript的開發(fā)變得更加容易而創(chuàng)建的。推薦先精通JS的的前提下再學(xué)習(xí)TS,這樣更有利于同時學(xué)習(xí)兩門語言。2022-12-12typescript難學(xué)嗎?前端有必要學(xué)?該怎么學(xué)typescript
TypeScript代碼與?JavaScript?代碼有非常高的兼容性,無門檻,你把?JS?代碼改為?TS?就可以運行。TypeScript?應(yīng)該不會脫離?JavaScript?成為獨立的語言。學(xué)習(xí)?TypeScript?應(yīng)該主要指的是學(xué)習(xí)它的類型系統(tǒng)。2022-12-12開發(fā)typescript項目tsconfig.json配置及選項使用解析
這篇文章主要為大家介紹了tsconfig.json配置及選項使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07PureScript與JavaScript中equality設(shè)計的使用對比分析
這篇文章主要為大家介紹了PureScript中的equality與JavaScript中的equality設(shè)計對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11