Typescript?extends?關鍵字繼承類型約束及條件類型判斷實現(xiàn)示例解析
引言
最近團隊新增了一個 HC,面試候選人的過程中,看他簡歷,履歷很牛逼,并且里面寫的精通 TypeScript。
我想那我們就問一個很基礎的問題吧,你了解 Typscript 的 extends 關鍵字嗎?它都會在那幾個場景下使用?
結果很失望,即使在我寫出了 extends 的使用方式時,這位哥們還沒想起怎么用,只能含糊其辭。
我趕緊換了一個問題,避免太尷尬:你了解 ts 工具類型 Exclude 與 Omit 的使用嗎?及它們兩個的區(qū)別?
這哥們還是不會~
不出意外的一面就掛了,說這個事的原因是,現(xiàn)在經(jīng)濟下行、市場上是狼多肉少,大家一定要珍惜面試機會,實事求是,平時多積累、多梳理,戰(zhàn)時抓機會、少冷場啊。
好了下面說正事。
extends 關鍵字實現(xiàn)繼承
如果你有看過 TypeScript 官方文檔,起碼熟悉這兩個:
extends關鍵字可以實現(xiàn)interface類型的擴展,- 這個也是
interface與type類型別名實現(xiàn)擴展的區(qū)別之一,類型別名通過&交叉類型來實現(xiàn)類型擴展
- 這個也是
extends關鍵字可用于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,可以通過從一個 類型中選取一組屬性集合來構造一個新的類型。
接下來讓我們實現(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 類型體操基礎動作中,有一種動作叫:條件類型,條件類型主要用于去判斷兩個類型之間的關系。
建議閱讀 類型體操基礎動作
比如工具類型 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 工具類型,可以做到將對象類型的所有屬性轉為只讀:
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)對字符串類型的駝峰轉橫杠:
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 關鍵字的三個妙用的詳細內容,更多關于Typescript extends 關鍵字的資料請關注腳本之家其它相關文章!
相關文章
TypeScript中的數(shù)據(jù)類型enum?type?interface基礎用法示例
這篇文章主要為大家介紹了TypeScript中的數(shù)據(jù)類型enum?type?interface基礎用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
PureScript與JavaScript中equality設計的使用對比分析
這篇文章主要為大家介紹了PureScript中的equality與JavaScript中的equality設計對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11
TypeScript與JavaScript的區(qū)別分析
TypeScript可以使用JavaScript中的所有代碼和編程概念,TypeScript是為了使JavaScript的開發(fā)變得更加容易而創(chuàng)建的。推薦先精通JS的的前提下再學習TS,這樣更有利于同時學習兩門語言。2022-12-12

