<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Typescript 最佳實踐

      文章列表: 

       

      為了更好的閱讀體驗,  可以看. 

       

      一年前剛接觸 Typescript 的時候, 覺得它加大了代碼工作量. 寫一大堆東西.為了找某個類型東奔西跑, 引入第三庫還經常報錯. 

      然而現在的我想說: 真香. 

      我們經常吐槽別人代碼可維護性特別低, 總是希望別人能夠主動的寫注釋, 可是寫注釋卻沒有任何方式可以進行約束. 這下好了, 類型就是最好的注釋, 用 Typescript, 可以大大提高代碼的可維護性. 

       

       

      一. 如何處理第三方庫類型相關問題

      Typescipt 所提供的第三方庫類型定義不僅約束我們的輸入調用, 還能為我們提供文檔. 現在, NPM 上的第三方類型定義種類繁多,很難保證類型定義是正確的. 也很難保證所有使用的第三方庫都有類型定義. 

      那么, 在這個充滿未知的過程中,如何才能正確使用TypeScript中的第三方庫呢?

       

      下面列舉了四種常見的無法正常工作的場景以及對應的解決方法:

      • 庫本身沒有自帶類型定義

      • 庫本身沒有類型定義, 也沒有相關的@type

      • 類型聲明庫有誤

      • 類型聲明報錯

       

      1. 庫本身沒有自帶類型定義

      查找不到相關的庫類型. 舉個栗子 

      在初次將 react 改造支持 typescript 時, 想必很多人都會遇到 module.hot 報錯. 此時只需要安裝對應的類型庫即可. 

      安裝 @types/webpack-env

       

      2. 庫本身沒有類型定義, 也沒有相關的@type

      那只能自己聲明一個了. 隨便舉個栗子. 

      declare module "lodash"

       

      3. 類型聲明庫有誤

      • 推動解決官方類型定義的問題, 提issue, pr 

      • Import 后通過 extends 或者 merge 能力對原類型進行擴展

      • 忍受類型的丟失或不可靠性

      • 使用 // @ts-ignore  忽略

       

      4. 類型聲明報錯

      • 在 compilerOptions 的添加"skipLibCheck": true, 曲線救國

       

      二. 巧用類型收縮解決報錯下面列舉了幾種常見的解決方法:

      • 類型斷言

      • 類型守衛 typeof in instanceof 字面量類型保護

      • 雙重斷言

       

      1、 類型斷言

      類型斷言可以明確的告訴 TypeScript 值的詳細類型,

      在某些場景, 我們非常確認它的類型, 即使與 typescript 推斷出來的類型不一致. 那我們可以使用類型斷言. 

      語法如下: 

      <類型>值

       

      值 as 類型 // 推薦使用這種語法. 因為<>容易跟泛型, react 中的語法起沖突

       

      舉個例子, 如下代碼,  padding 值可以是 string , 也可以是 number, 雖然在代碼里面寫了 Array(), 我們明確的知道, padding 會被parseint 轉換成 number 類型, 但類型定義依然會報錯. 

       

      function padLeft(value: string, padding: string | number) {

         // 報錯: Operator '+' cannot be applied to

         // types 'string | number' and 'number'

         return Array(padding + 1).join(" ") + value;

      }

       

      解決方法, 使用類型斷言. 告訴 typescript 這里我確認它是 number 類型, 忽略報錯. 

      function padLeft(value: string, padding: string | number) {

         // 正常

         return Array(padding as number + 1).join(" ") + value;

      }

       

      但是如果有下面這種情況, 我們要寫很多個 as 么? 

      function padLeft(value: string, padding: string | number) {

         console.log((padding as number) + 3);

         console.log((padding as number) + 2);

         console.log((padding as number) + 5);

         return Array((padding as number) + 1).join(' ') + value;

      }

       

      2、 類型守衛

      類型守衛有以下幾種方式, 簡單的概括以下

      • typeof:  用于判斷 "number","string","boolean"或 "symbol" 四種類型. 

      • instanceof : 用于判斷一個實例是否屬于某個類

      • in: 用于判斷一個屬性/方法是否屬于某個對象

      • 字面量類型保護

       

      上面的例子中, 是 string | number 類型, 因此使用 typeof 來進行類型守衛. 例子如下: 

      function padLeft(value: string,padding: string | number) {

         if (typeof padding === 'number') {

             console.log(padding + 3); //正常

             console.log(padding + 2); //正常

             console.log(padding + 5); //正常

              //正常

             return Array(padding + 1).join(' ') value;

         }

         if (typeof padding === 'string') {

             return padding + value;

         }

      }

       

      相比較 類型斷言 as , 省去了大量代碼. 除了 typeof , 我們還有幾種方式, 下面一一舉例子. 

       

      • instanceof :用于判斷一個實例是否屬于某個類

      class Man {

         handsome = 'handsome';

      }

       

      class Woman {

         beautiful = 'beautiful';

      }

       

      function Human(arg: Man | Woman) {

         if (arg instanceof Man) {

             console.log(arg.handsome);

             console.log(arg.beautiful); // error

         } else {

             // 這一塊中一定是 Woman

             console.log(arg.beautiful);

         }

      }

       

      • in : 用于判斷一個屬性/方法是否屬于某個對象

      interface B {

         b: string;

      }

       

      interface A {

         a: string;

      }

       

      function foo(x: A | B) {

         if ('a' in x) {

             return x.a;

         }

         return x.b;

      }

       

      • 字面量類型保護

      有些場景, 使用 in, instanceof, typeof 太過麻煩. 這時候可以自己構造一個字面量類型. 

      type Man = {

         handsome: 'handsome';

         type: 'man';

       

      };

       

      type Woman = {

         beautiful: 'beautiful';

         type: 'woman';

      };

       

      function Human(arg: Man | Woman) {

         if (arg.type === 'man') {

             console.log(arg.handsome);

             console.log(arg.beautiful); // error

         } else {

             // 這一塊中一定是 Woman

             console.log(arg.beautiful);

         }

      }

       

      3、雙重斷言

      有些時候使用 as 也會報錯,因為 as 斷言的時候也不是毫無條件的. 它只有當S類型是T類型的子集,或者T類型是S類型的子集時,S能被成功斷言成T. 

      所以面對這種情況, 只想暴力解決問題的情況, 可以使用雙重斷言. 

      function handler(event: Event) {

         const element = event as HTMLElement;

         // Error: 'Event' 和 'HTMLElement'

          中的任何一個都不能賦值給另外一個

      }

       

      如果你仍然想使用那個類型,你可以使用雙重斷言。首先斷言成兼容所有類型的any

       

      function handler(event: Event) {

         const element = (event as any) as HTMLElement;

          // 正常

      }

       

      三. 巧用 typescript 支持的 js 最新特性優化代碼

      1. 可選鏈 Optional Chaining 

       

      let x = foo?.bar.baz();

       

       

      typescript 中的實現如下: 

      var _a;

      let x = (_a = foo) === null ||

      _a === void 0 ? void 0 : _a.bar.baz();

       

      利用這個特性, 我們可以省去寫很多惡心的 a && a.b && a.b.c 這樣的代碼

       

      2. 空值聯合 Nullish Coalescing

       

      let x = foo ?? '22';

       

       

      typescript 中的實現如下: 

       

      let x = (foo !== null && foo !== void 0 ?

      foo : '22');

       

       

       

      四. 巧用高級類型靈活處理數據typescript 提供了一些很不錯的工具函數. 如下圖

       

       

       

       

      • 類型索引

      為了實現上面的工具函數, 我們需要先了解以下幾個語法: 

      keyof : 獲取類型上的 key 值

      extends : 泛型里面的約束

      T[K] : 獲取對象 T 相應 K 的元素類型

       

      type Partial<T> = {

         [P in keyof T]?: T[P]

      }

       

      在使用 props 的時候, 有時候全部屬性都是可選的, 如果一個一個屬性寫 ? , 大量的重復動作. 這種時候可以直接使用 Partial<State>  

       

      Record 作為一個特別靈活的工具. 第一個泛型傳入對象的key值, 第二個傳入 對象的屬性值. 

      type Record<K extends string, T> = {

         [P in K]: T;

      }

       

      我們看一下下面的這個對象, 你會怎么用 ts 聲明它? 

      const AnimalMap = {

         cat: { name: '貓', title: 'cat' },

         dog: { name: '狗', title: 'dog' },

         frog: { name: '蛙', title: 'wa' },

      };

       

      此時用 Record 即可. 

      type AnimalType = 'cat' | 'dog' | 'frog';

       

      interface AnimalDescription {

      name: string, title: string

      }

       

      const AnimalMap:

      Record<AnimalType, AnimalDescription> = {

         cat: { name: '貓', title: 'cat' },

         dog: { name: '狗', title: 'dog' },

         frog: { name: '蛙', title: 'wa' },

      };

       

      • never, 構造條件類型

      除了上面的幾個語法. 我們還可以用 never , 構造條件類型來組合出更靈活的類型定義. 

      語法: 

      never: 從未出現的值的類型

       

      // 如果 T 是 U 的子類型的話,那么就會返回 X,否則返回 Y

      構造條件類型 : T extends U ? X : Y

       

      type Exclude<T, U> = T extends U ? never : T;

       

      // 相當于: type A = 'a'

      type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>

       

      • 更簡潔的修飾符: - 與 + 

      可以直接去除 ? 將所有對象屬性變成必傳內容. 

      type Required<T> = { [P in keyof T]-?: T[P] };

       

      // Remove readonly

      type MutableRequired<T> = {

          -readonly [P in keyof T]: T[P]

      };  

       

      • infer: 在 extends 條件語句中待推斷的類型變量。 

      // 需要獲取到 Promise 類型里蘊含的值

      type PromiseVal<P> =

      P extends Promise<infer INNER> ? INNER : P;

       

      type PStr = Promise<string>;

       

      // Test === string

      type Test = PromiseVal<PStr>;

       

       

      五. 辨別 type & interface 

      在各大類型庫中, 會看到形形色色的 type 和 interface . 然而很多人在實際中卻不知道它們的區別. 

       

      官網的定義如下: 

       

      An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.

       

      An interface can have multiple merged declarations, but a type alias for an object type literal cannot.

       

      從一張圖看出它們兩的區別: 

       

       

       

       

      建議:  能用 interface 實現,就用 interface , 如果不能才用 type. 

       

       

       

      為了更好的閱讀體驗,  《typescrit 最佳實踐》

      - 歡迎關注「前端加加」,認真學前端,做個有專業的技術人...

       

      posted @ 2019-12-30 10:01  beidan  閱讀(1407)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 成人午夜福利精品一区二区| 日韩有码av中文字幕| 国产精品亚洲二区在线播放| 国产中文字幕一区二区| 一本久道久久综合久久鬼色| 日韩毛片在线视频x| 欧美变态另类zozo| 亚洲国产成人精品av区按摩| 国产揄拍国产精品| 国产一国产精品免费播放| 久久国产精品老人性| 国产视频不卡一区二区三区 | 国产一区二区av天堂热| 国产内射XXXXX在线| av中文字幕在线二区| 精品久久综合日本久久网| 亚洲成人www| 污网站在线观看视频| 亚洲av成人区国产精品| 国产精品香港三级国产av| 久久99精品久久久久久齐齐| 亚洲中少妇久久中文字幕| 老色批国产在线观看精品| 人妻内射一区二区在线视频| 日韩精品中文字幕第二页| 国产成人无码免费视频麻豆| 亚洲偷自拍国综合| 日韩精品一区二区在线看| 久久国产成人精品av| 久久久久亚洲AV色欲av| 国产精品一区中文字幕| 国产精品日韩中文字幕| 国产一区二区三区美女| 久久久亚洲欧洲日产国码aⅴ| 国产精品视频全国免费观看| 东京热一区二区三区在线| 在线天堂www在线| 性色av 一区二区三区| 四虎精品国产永久在线观看| 欧美野外伦姧在线观看| 欧美肥妇毛多水多bbxx|