欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Typescript?extends?關(guān)鍵字繼承類型約束及條件類型判斷實現(xiàn)示例解析

 更新時間:2023年08月16日 08:48:16   作者:劍大瑞  
這篇文章主要介紹了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 extends 關(guān)鍵字的三個妙用的詳細內(nèi)容,更多關(guān)于Typescript extends 關(guān)鍵字的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論