<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>

          【TS】1102- TypeScript高級類型入門手冊,附大量代碼實例

          共 9352字,需瀏覽 19分鐘

           ·

          2021-10-09 11:50

          作者:望道

          https://juejin.cn/post/6904150785966211086

          TypeScript 是一種類型化的語言,允許你指定變量的類型,函數(shù)參數(shù),返回的值和對象屬性。

          你可以把本文看做一個帶有示例的 TypeScript 高級類型備忘單

          讓我們開始吧!

          Intersection Types(交叉類型)

          交叉類型是一種將多種類型組合為一種類型的方法。這意味著你可以將給定的類型 A 與類型 B 或更多類型合并,并獲得具有所有屬性的單個類型。

          type LeftType = {
          id: number;
          left: string;
          };

          type RightType = {
          id: number;
          right: string;
          };

          type IntersectionType = LeftType & RightType;

          function showType(args: IntersectionType) {
          console.log(args);
          }

          showType({ id: 1, left: 'test', right: 'test' });
          // Output: {id: 1, left: "test", right: "test"}

          如你所見,IntersectionType組合了兩種類型-LeftTypeRightType,并使用符號形成了交叉類型。

          Union Types(聯(lián)合類型)

          聯(lián)合類型使你可以賦予同一個變量不同的類型

          type UnionType = string | number;

          function showType(arg: UnionType) {
          console.log(arg);
          }

          showType('test');
          // Output: test

          showType(7);
          // Output: 7

          函數(shù)showType是一個聯(lián)合類型函數(shù),它接受字符串或者數(shù)字作為參數(shù)。

          Generic Types(泛型)

          泛型類型是復用給定類型的一部分的一種方式。它有助于捕獲作為參數(shù)傳遞的類型 T。

          優(yōu)點: 創(chuàng)建可重用的函數(shù),一個函數(shù)可以支持多種類型的數(shù)據(jù)。這樣開發(fā)者就可以根據(jù)自己的數(shù)據(jù)類型來使用函數(shù)

          泛型函數(shù)

          function showType<T>(args: T) {
          console.log(args);
          }

          showType('test');
          // Output: "test"

          showType(1);
          // Output: 1

          如何創(chuàng)建泛型類型:需要使用<>并將?T(名稱可自定義)作為參數(shù)傳遞。上面的 ?? 栗子中, 我們給?showType?添加了類型變量?T。T幫助我們捕獲用戶傳入的參數(shù)的類型(比如:number/string)之后我們就可以使用這個類型

          我們把?showType?函數(shù)叫做泛型函數(shù),因為它可以適用于多個類型

          泛型接口

          interface GenericType {
          id: number;
          name: T;
          }

          function showType(args: GenericType<string>) {
          console.log(args);
          }

          showType({ id: 1, name: 'test' });
          // Output: {id: 1, name: "test"}

          function showTypeTwo(args: GenericType<number>) {
          console.log(args);
          }

          showTypeTwo({ id: 1, name: 4 });
          // Output: {id: 1, name: 4}

          在上面的栗子中,聲明了一個?GenericType?接口,該接口接收泛型類型?T, 并通過類型?T來約束接口內?name?的類型

          注:泛型變量約束了整個接口后,在實現(xiàn)的時候,必須指定一個類型

          因此在使用時我們可以將name設置為任意類型的值,示例中為字符串或數(shù)字

          多參數(shù)的泛型類型

          interface GenericType {
          id: T;
          name: U;
          }

          function showType(args: GenericType<number, string>) {
          console.log(args);
          }

          showType({ id: 1, name: 'test' });
          // Output: {id: 1, name: "test"}

          function showTypeTwo(args: GenericType<string, string[]>) {
          console.log(args);
          }

          showTypeTwo({ id: '001', name: ['This', 'is', 'a', 'Test'] });
          // Output: {id: "001", name: Array["This", "is", "a", "Test"]}

          泛型類型可以接收多個參數(shù)。在上面的代碼中,我們傳入兩個參數(shù):TU,然后將它們用作id,name的類型。也就是說,我們現(xiàn)在可以使用該接口并提供不同的類型作為參數(shù)。

          Utility Types

          TypeScript 內部也提供了很多方便實用的工具,可幫助我們更輕松地操作類型。如果要使用它們,你需要將類型傳遞給<>

          Partial

          • Partial

          Partial 允許你將T類型的所有屬性設為可選。它將在每一個字段后面添加一個?。

          interface PartialType {
          id: number;
          firstName: string;
          lastName: string;
          }

          /*
          等效于
          interface PartialType {
          id?: number
          firstName?: string
          lastName?: string
          }
          */


          function showType(args: Partial) {
          console.log(args);
          }

          showType({ id: 1 });
          // Output: {id: 1}

          showType({ firstName: 'John', lastName: 'Doe' });
          // Output: {firstName: "John", lastName: "Doe"}

          上面代碼中聲明了一個PartialType接口,它用作函數(shù)showType()的參數(shù)的類型。為了使所有字段都變?yōu)榭蛇x,我們使用Partial關鍵字并將PartialType類型作為參數(shù)傳遞。

          Required

          • Required

          將某個類型里的屬性全部變?yōu)楸剡x項

          interface RequiredType {
          id: number;
          firstName?: string;
          lastName?: string;
          }

          function showType(args: Required) {
          console.log(args);
          }

          showType({ id: 1, firstName: 'John', lastName: 'Doe' });
          // Output: { id: 1, firstName: "John", lastName: "Doe" }

          showType({ id: 1 });
          // Error: Type '{ id: number: }' is missing the following properties from type 'Required': firstName, lastName

          上面的代碼中,即使我們在使用接口之前先將某些屬性設為可選,但Required被加入后也會使所有屬性成為必選。如果省略某些必選參數(shù),TypeScript 將報錯。

          Readonly

          • Readonly

          會轉換類型的所有屬性,以使它們無法被修改

          interface ReadonlyType {
          id: number;
          name: string;
          }

          function showType(args: Readonly) {
          args.id = 4;
          console.log(args);
          }

          showType({ id: 1, name: 'Doe' });
          // Error: Cannot assign to 'id' because it is a read-only property.

          我們使用Readonly來使ReadonlyType的屬性不可被修改。也就是說,如果你嘗試為這些字段之一賦予新值,則會引發(fā)錯誤。

          除此之外,你還可以在指定的屬性前面使用關鍵字readonly使其無法被重新賦值

          interface ReadonlyType {
          readonly id: number;
          name: string;
          }

          Pick

          • Pick

          此方法允許你從一個已存在的類型?T中選擇一些屬性作為K, 從而創(chuàng)建一個新類型

          即 抽取一個類型/接口中的一些子集作為一個新的類型

          T代表要抽取的對象?K有一個約束: 一定是來自T所有屬性字面量的聯(lián)合類型 新的類型/屬性一定要從K中選取,

          /**
          源碼實現(xiàn)
          * From T, pick a set of properties whose keys are in the union K
          */

          type Pickextends keyof T> = {
          [P in K]: T[P];
          };
          interface PickType {
          id: number;
          firstName: string;
          lastName: string;
          }

          function showType(args: Pick) {
          console.log(args);
          }

          showType({ firstName: 'John', lastName: 'Doe' });
          // Output: {firstName: "John"}

          showType({ id: 3 });
          // Error: Object literal may only specify known properties, and 'id' does not exist in type 'Pick'

          Pick?與我們前面討論的工具有一些不同,它需要兩個參數(shù)

          • T是要從中選擇元素的類型
          • K是要選擇的屬性(可以使使用聯(lián)合類型來選擇多個字段)

          Omit

          • Omit

          Omit的作用與Pick類型正好相反。不是選擇元素,而是從類型T中刪除K個屬性。

          interface PickType {
          id: number;
          firstName: string;
          lastName: string;
          }

          function showType(args: Omit) {
          console.log(args);
          }

          showType({ id: 7 });
          // Output: {id: 7}

          showType({ firstName: 'John' });
          // Error: Object literal may only specify known properties, and 'firstName' does not exist in type 'Pick'

          Extract

          • Extract

          提取T中可以賦值給U的類型--取交集

          Extract允許你通過選擇兩種不同類型中的共有屬性來構造新的類型。也就是從T中提取所有可分配給U的屬性。

          interface FirstType {
          id: number;
          firstName: string;
          lastName: string;
          }

          interface SecondType {
          id: number;
          address: string;
          city: string;
          }

          type ExtractType = Extract;
          // Output: "id"

          在上面的代碼中,FirstType接口和SecondType接口,都存在?id:number屬性。因此,通過使用Extract,即提取出了新的類型?{id:number}。

          Exclude

          Exclude?--從?T?中剔除可以賦值給?U?的類型。

          Extract不同,Exclude通過排除兩個不同類型中已經存在的共有屬性來構造新的類型。它會從T中排除所有可分配給U的字段。

          interface FirstType {
          id: number;
          firstName: string;
          lastName: string;
          }

          interface SecondType {
          id: number;
          address: string;
          city: string;
          }

          type ExcludeType = Exclude;

          // Output; "firstName" | "lastName"

          上面的代碼可以看到,屬性firstNamelastName?在SecondType類型中不存在。通過使用Extract關鍵字,我們可以獲得T中存在而U中不存在的字段。

          Record

          • Record

          此工具可幫助你構造具有給定類型T的一組屬性K的類型。將一個類型的屬性映射到另一個類型的屬性時,Record非常方便。

          interface EmployeeType {
          id: number;
          fullname: string;
          role: string;
          }

          let employees: Record<number, EmployeeType> = {
          0: { id: 1, fullname: 'John Doe', role: 'Designer' },
          1: { id: 2, fullname: 'Ibrahima Fall', role: 'Developer' },
          2: { id: 3, fullname: 'Sara Duckson', role: 'Developer' },
          };

          // 0: { id: 1, fullname: "John Doe", role: "Designer" },
          // 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
          // 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }

          Record的工作方式相對簡單。在代碼中,它期望一個number作為類型,這就是為什么我們將 0、1 和 2 作為employees變量的鍵的原因。如果你嘗試使用字符串作為屬性,則會引發(fā)錯誤,因為屬性是由EmployeeType給出的具有 ID,fullName 和 role 字段的對象。

          NonNullable

          • NonNullable

          -- 從?T?中剔除?null?和?undefined

          type NonNullableType = string | number | null | undefined;

          function showType(args: NonNullable) {
          console.log(args);
          }

          showType('test');
          // Output: "test"

          showType(1);
          // Output: 1

          showType(null);
          // Error: Argument of type 'null' is not assignable to parameter of type 'string | number'.

          showType(undefined);
          // Error: Argument of type 'undefined' is not assignable to parameter of type 'string | number'.

          我們將類型NonNullableType作為參數(shù)傳遞給NonNullable,NonNullable通過排除nullundefined來構造新類型。也就是說,如果你傳遞可為空的值,TypeScript 將引發(fā)錯誤。

          順便說一句,如果將--strictNullChecks標志添加到tsconfig文件,TypeScript 將應用非空性規(guī)則。

          Mapped Types( 映射類型)

          映射類型允許你從一個舊的類型,生成一個新的類型。

          請注意,前面介紹的某些高級類型也是映射類型。如:

          /*
          Readonly, Partial和 Pick是同態(tài)的,但 Record不是。因為 Record并不需要輸入類型來拷貝屬性,所以它不屬于同態(tài):
          */

          type Readonly = {
          readonly [P in keyof T]: T[P];
          };
          type Partial = {
          [P in keyof T]?: T[P];
          };
          type Pickextends keyof T> = {
          [P in K]: T[P];
          };

          Record;
          type StringMap = {
          [P in keyof T]: string;
          };

          function showType(arg: StringMap<{ id: number; name: string }>) {
          console.log(arg);
          }

          showType({ id: 1, name: 'Test' });
          // Error: Type 'number' is not assignable to type 'string'.

          showType({ id: 'testId', name: 'This is a Test' });
          // Output: {id: "testId", name: "This is a Test"}

          StringMap<>會將傳入的任何類型轉換為字符串。就是說,如果我們在函數(shù)showType()中使用它,則接收到的參數(shù)必須是字符串-否則,TypeScript 將引發(fā)錯誤。

          Type Guards(類型保護)

          類型保護使你可以使用運算符檢查變量或對象的類型。這是一個條件塊,它使用typeof,instanceofin返回類型。

          typescript 能夠在特定區(qū)塊中保證變量屬于某種確定類型??梢栽诖藚^(qū)塊中放心地引用此類型的屬性,或者調用此類型的方法

          typeof

          function showType(x: number | string) {
          if (typeof x === 'number') {
          return `The result is ${x + x}`;
          }
          throw new Error(`This operation can't be done on a ${typeof x}`);
          }

          showType("I'm not a number");
          // Error: This operation can't be done on a string

          showType(7);
          // Output: The result is 14

          什么代碼中,有一個普通的 JavaScript 條件塊,通過typeof檢查接收到的參數(shù)的類型。

          instanceof

          class Foo {
          bar() {
          return 'Hello World';
          }
          }

          class Bar {
          baz = '123';
          }

          function showType(arg: Foo | Bar) {
          if (arg instanceof Foo) {
          console.log(arg.bar());
          return arg.bar();
          }

          throw new Error('The type is not supported');
          }

          showType(new Foo());
          // Output: Hello World

          showType(new Bar());
          // Error: The type is not supported

          像前面的示例一樣,這也是一個類型保護,它檢查接收到的參數(shù)是否是Foo類的一部分,并對其進行處理。

          in

          interface FirstType {
          x: number;
          }
          interface SecondType {
          y: string;
          }

          function showType(arg: FirstType | SecondType) {
          if ('x' in arg) {
          console.log(`The property ${arg.x} exists`);
          return `The property ${arg.x} exists`;
          }
          throw new Error('This type is not expected');
          }

          showType({ x: 7 });
          // Output: The property 7 exists

          showType({ y: 'ccc' });
          // Error: This type is not expected

          什么的栗子中,使用in檢查參數(shù)對象上是否存在屬性x。

          Conditional Types(條件類型)

          條件類型測試兩種類型,然后根據(jù)該測試的結果選擇其中一種。

          一種由條件表達式所決定的類型, 表現(xiàn)形式為?T extends U ? X : Y?, 即如果類型T可以被賦值給類型U,那么結果類型就是X類型,否則為Y類型。

          條件類型使類型具有了不唯一性,增加了語言的靈活性,

          // 源碼實現(xiàn)
          type NonNullable = T extends null | undefined ? never : T;

          // NotNull 等價于 NoneNullable

          // 用法示例
          type resType = NonNullable<string | number | null | undefined>; // string|number

          上面的代碼中,?NonNullable檢查類型是否為?null,并根據(jù)該類型進行處理。正如你所看到的,它使用了 JavaScript 三元運算符。

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設計模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 120+篇原創(chuàng)系列匯總

          回復“加群”與大佬們一起交流學習~

          點擊“閱讀原文”查看 120+ 篇原創(chuàng)文章

          瀏覽 24
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  成人电影1区 | 日韩无码成人一区黄色电影 | 安徽BBBBB视频BBB | 天天日日天天干 | 色老太老太色CD |