<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你應(yīng)該掌握的 5 大 TypeScript 功能

          共 5000字,需瀏覽 10分鐘

           ·

          2021-08-15 21:59

          英文 | https://betterprogramming.pub/top-5-typescript-features-you-should-master-2358db9ab3d5

          翻譯 | 楊小二


          TypeScript 的影響力與日俱增。它現(xiàn)在是任何新的 Web/Node 項(xiàng)目的首選配套工具。使用 TypeScript 的好處怎么強(qiáng)調(diào)都不為過。然而,了解和理解這個(gè) JavaScript 超集擁有的所有工具是很重要的。

          你是否正在投入時(shí)間來提高你的TypeScript技能?你想充分利用它嗎?有時(shí),由于沒有使用正確的 TypeScript 功能并且沒有遵循其最佳實(shí)踐,可能會(huì)出現(xiàn)大量代碼重復(fù)和樣板。

          在本文中,我們將研究 TypeScript 可以賦予我們的五個(gè)最重要的功能。通過確保并了解它們的用例,我們可以構(gòu)建更好、更全面的代碼庫。

          1、Unions

          聯(lián)合是最基本且易于使用的 TypeScript 功能之一。它們讓我們可以輕松地將多種類型合二為一。交集和聯(lián)合類型是我們組合類型的方法之一。

          function logIdentifier(id: string | number) {  console.log('id', id);}

          當(dāng)我們想要表示某個(gè)類型可以為空時(shí),它們非常有用:

          function logIdentifier(id: string | undefined) {  if(!id) {    console.error('no identifier found');  } else {    console.log('id', id);  }}

          不僅限于未定義或原語。它們可用于任何接口或類型。

          interface Vehicle {  speed: number;}interface Bike extends Vehicle {  ride: () => void;}interface Plane extends Vehicle {  fly: () => void;}function useVehicle(vehicle: Bike | Plane) {  ...}

          鑒于上面的聯(lián)合類型,我們?nèi)绾螀^(qū)分自行車和飛機(jī)?通過使用可區(qū)分聯(lián)合功能。我們將創(chuàng)建一個(gè)名為 Vehicles 的枚舉并將其用作屬性值。

          看看代碼如何:

          enum Vehicles {    bike,    plane}
          interface Vehicle { speed: number; type: Vehicles;}
          interface Bike extends Vehicle { ride: () => void; type: Vehicles.bike;}
          interface Plane extends Vehicle { fly: () => void; type: Vehicles.plane;}
          function useVehicle(vehicle: Bike | Plane) { if (vehicle.type === Vehicles.bike) { vehicle.ride(); }
          if (vehicle.type === Vehicles.plane) { vehicle.fly(); }}

          從而,我們可以看到Unions是一個(gè)簡單而強(qiáng)大的工具,它有一些技巧。但是,如果我們想以更強(qiáng)大和動(dòng)態(tài)的方式表達(dá)類型/接口,我們需要使用泛型。

          2、泛型

          使我們的方法/API 可重用的最佳方法是什么?泛型! 這是大多數(shù)類型語言中的一項(xiàng)功能。它讓我們以更通用的方式表達(dá)類型。這將賦予我們的類和類型。

          讓我們從一個(gè)基本的例子開始。讓我們創(chuàng)建一個(gè)方法來將任何定義的類型添加到數(shù)組中:

          function addItem(item: string, array: string[]) {  array = [...array, item];  return array;}

          如果我們想為 int 類型創(chuàng)建相同的實(shí)用程序怎么辦?我們應(yīng)該重做同樣的方法嗎?通過簡單地使用泛型,我們可以重用代碼而不是添加更多樣板:

          function addItem<T>(item: T, array: T[]) {  array = [...array, item];  return array;}
          addItem('hello', []);
          addItem(true, [true, true]);

          我們?nèi)绾畏乐乖?T 中使用不需要的類型?為此,我們可以使用 extends 關(guān)鍵字:

          function addItem<T extends boolean | string>(item: T, array: T[]) {  array = [...array, item];  return array;}
          addItem('hello', []);
          addItem(true, [true, true]);
          addItem(new Date(), []);// ^^^^^^^^^^// Argument of type 'Date' is not assignable to parameter of type 'string | boolean'

          泛型將使我們能夠?yàn)槲覀兊念愋蜆?gòu)建全面和動(dòng)態(tài)的接口。它們是必須掌握的功能,需要在我們的日常開發(fā)中出現(xiàn)。

          3、元組

          什么是元組?我們來看看定義:

          元組類型允許你用固定數(shù)量的元素來表達(dá)數(shù)組,這些元素的類型是已知的,但不必相同。例如,你可能希望將一個(gè)值表示為一對(duì)字符串和一個(gè)數(shù)字。” 

          ——TypeScript 的文檔

          最重要的一點(diǎn)是這些數(shù)組的值長度是固定的。定義元組有兩種方式:

          明確:

          const array: [string, number] = ['test', 12];

          隱含地:

          const array = ['test', 12] as const;

          唯一的區(qū)別是 as const 將使數(shù)組只讀,這在我看來是可取的。

          請(qǐng)注意,元組也可以被標(biāo)記:

          function foo(x: [startIndex: number, endIndex: number]) {  ...}

          標(biāo)簽不需要我們?cè)诮鈽?gòu)時(shí)以不同的方式命名我們的變量。它們純粹是為了文檔和工具。標(biāo)簽將有助于使我們的代碼更具可讀性和可維護(hù)性。

          請(qǐng)注意,使用標(biāo)記元組時(shí)有一個(gè)重要規(guī)則:標(biāo)記元組元素時(shí),元組中的所有其他元素也必須被標(biāo)記。

          4、映射類型

          什么是映射類型?它們是一種避免反復(fù)定義接口的方法。你可以將類型建立在另一種類型或接口的基礎(chǔ)上,從而節(jié)省手動(dòng)工作。

          “當(dāng)你不想重復(fù)時(shí),有時(shí)一種類型需要基于另一種類型。映射類型建立在索引簽名的語法之上,用于聲明尚未提前聲明的屬性類型。” — TypeScript 的文檔

          總而言之,映射類型允許我們基于現(xiàn)有類型創(chuàng)建新類型。

          TypeScript 確實(shí)附帶了很多實(shí)用程序類型,因此我們不必在每個(gè)項(xiàng)目中重寫它們。

          讓我們看看一些最常見的:Omit、Partial、Readonly、Readonly、Exclude、Extract、NonNullable 和 ReturnType。

          讓我們看看其中的一個(gè)再行動(dòng)。假設(shè)我們要將名為 Teacher 的實(shí)體的所有屬性轉(zhuǎn)換為只讀。我們可以使用什么實(shí)用程序?

          我們可以使用 Readonly 實(shí)用程序類型。讓我們看看它的實(shí)際效果:

          interface Teacher {  name: string;  email: string;}
          type ReadonlyTeacher = Readonly<Teacher>;
          const t: ReadonlyTeacher = { name: 'jose', email: '[email protected]'};
          t.name = 'max'; // Error: Cannot assign to 'name' because it is a read-only property.(2540)

          讓我們回顧一下Readonly 在底層是如何工作的:

          type Readonly<T> = { readonly [P in keyof T]: T[P]; }

          現(xiàn)在讓我們創(chuàng)建我們的自定義實(shí)用程序以獲得樂趣。讓我們反轉(zhuǎn) Readonly 類型以創(chuàng)建一個(gè) Writable 類型:

          interface Teacher {  readonly name: string;  readonly email: string;}
          type Writeable<T> = { -readonly [P in keyof T]: T[P] };
          const t: Writeable<Teacher> = { name: 'jose', email: '[email protected]' };
          t.name = 'max'; // works fine

          注意:注意 - 修飾符。在這種情況下,它用于刪除 readonly 修飾符。它可用于從屬性中刪除其他修飾符,例如 ?。

          5、類型保護(hù)

          類型保護(hù)是一組幫助我們縮小對(duì)象類型的工具。這意味著我們可以從更一般的類型轉(zhuǎn)到更具體的類型。

          有多種技術(shù)可以執(zhí)行類型保護(hù)。在本文中,我們將只關(guān)注用戶定義的類型保護(hù)。這些基本上是斷言——就像任何給定類型的函數(shù)一樣。

          我們?nèi)绾问褂盟鼈儯课覀冎恍枰x一個(gè)函數(shù),它的返回類型是一個(gè)類型謂詞,它返回true/false。讓我們看看如何將 typeof 運(yùn)算符轉(zhuǎn)換為類型保護(hù)函數(shù):

          function isNumber(x: any): x is number {  return typeof x === "number";}
          function add1(value: string | number) { if (isNumber(value)) { return value +1; } return +value + 1;}

          請(qǐng)注意,如果 isNumber 檢查為 false,則 TypeScript 可以假定 value 將是一個(gè)字符串,因?yàn)?x 可能是字符串或數(shù)字。

          讓我們看另一個(gè)使用自定義接口的類型保護(hù)示例:

          interface Hunter {    hunt: () => void;}
          // function type guardfunction isHunter(x: unknown): x is Hunter { return (x as Hunter).hunt !== undefined;}
          const performAction = (x: unknown) => { if (isHunter(x)) { x.hunt(); }}
          const animal = { hunt: () => console.log('hunt')}
          performAction(animal);
          注意 isHunter 函數(shù)的返回類型是 x is Hunter。該斷言函數(shù)將成為我們的類型保護(hù)。
          類型保護(hù)是有作用域的。在 isHunter(x) 代碼塊中,x 變量的類型為 Hunter。這意味著我們可以安全地調(diào)用它的hunt 方法。然而,在這個(gè)代碼塊之外,x 類型仍然是未知的。
          最后的想法
          在本文中,我們只是探討了我們可以使用的最重要的 Typescript 功能。由于這只是一個(gè)概述,我們只是觸及了它們的表面。
          我的目標(biāo)是讓你好奇并展示 Typescript 的能力?,F(xiàn)在由你來進(jìn)一步深入研究其中任何一個(gè)。
          通過嘗試逐步采用它們,你將看到你的代碼如何變得更整潔、更干凈、更易于維護(hù)。
          感謝你的閱讀,祝編程愉快!

          學(xué)習(xí)更多技能

          請(qǐng)點(diǎn)擊下方公眾號(hào)


          瀏覽 55
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品www...xxc | 国产中文人人国际 | aaa久久久国产 | 人妻体内射精一区二区三区 | 先锋av资源在线 先锋影音成人在线 |