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

          typescript 高級技巧

          共 5149字,需瀏覽 11分鐘

           ·

          2021-08-09 21:18

          用了一段時間的 typescript 之后,深感中大型項目中 typescript 的必要性,它能夠提前在編譯期避免許多 bug,如很惡心的拼寫問題。而越來越多的 package 也開始使用 ts,學(xué)習(xí) ts 已是勢在必行。

          以下是我在工作中總結(jié)到的比較實用的 typescript 技巧。

          01 keyof

          keyofObject.keys 略有相似,只不過 keyofinterface 的鍵。

          interface Point {    x: number;    y: number;}
          // type keys = "x" | "y"type keys = keyof Point;

          假設(shè)有一個 object 如下所示,我們需要使用 typescript 實現(xiàn)一個 get 函數(shù)來獲取它的屬性值

          const data = {  a: 3,  hello: 'world'}
          function get(o: object, name: string) { return o[name]}

          我們剛開始可能會這么寫,不過它有很多缺點

          1. 無法確認返回類型:這將損失 ts 最大的類型校驗功能
          2. 無法對 key 做約束:可能會犯拼寫錯誤的問題

          這時可以使用 keyof 來加強 get 函數(shù)的類型功能,有興趣的同學(xué)可以看看 _.get 的 type 標(biāo)記以及實現(xiàn)

          function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {  return o[name]}

          02 Required & Partial & Pick

          既然了解了 keyof,可以使用它對屬性做一些擴展, 如實現(xiàn) PartialPickPick 一般用在 _.pick

          type Partial<T> = {  [P in keyof T]?: T[P];};
          type Required<T> = { [P in keyof T]-?: T[P];};
          type Pick<T, K extends keyof T> = { [P in K]: T[P];};
          interface User { id: number; age: number; name: string;};
          // 相當(dāng)于: type PartialUser = { id?: number; age?: number; name?: string; }type PartialUser = Partial<User>
          // 相當(dāng)于: type PickUser = { id: number; age: number; }type PickUser = Pick<User, "id" | "age">

          這幾個類型已內(nèi)置在 Typescript 中

          03 Condition Type

          類似于 js 中的 ?: 運算符,可以使用它擴展一些基本類型

          T extends U ? X : Y
          type isTrue<T> = T extends true ? true : false// 相當(dāng)于 type t = falsetype t = isTrue<number>
          // 相當(dāng)于 type t = falsetype t1 = isTrue<false>

          04 never & Exclude & Omit

          官方文檔對 never 的描述如下

          the never type represents the type of values that never occur.

          結(jié)合 neverconditional type 可以推出很多有意思而且實用的類型,比如 Omit

          type Exclude<T, U> = T extends U ? never : T;
          // 相當(dāng)于: type A = 'a'type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>

          結(jié)合 Exclude 可以推出 Omit 的寫法

          type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
          interface User { id: number; age: number; name: string;};
          // 相當(dāng)于: type PickUser = { age: number; name: string; }type OmitUser = Omit<User, "id">

          05 typeof

          顧名思義,typeof 代表取某個值的 type,可以從以下示例來展示他們的用法

          const a: number = 3
          // 相當(dāng)于: const b: number = 4const b: typeof a = 4

          在一個典型的服務(wù)端項目中,我們經(jīng)常需要把一些工具塞到 context 中,如config,logger,db models, utils 等,此時就使用到 typeof

          import logger from './logger'import utils from './utils'
          interface Context extends KoaContect { logger: typeof logger, utils: typeof utils}
          app.use((ctx: Context) => { ctx.logger.info('hello, world')
          // 會報錯,因為 logger.ts 中沒有暴露此方法,可以最大限度的避免拼寫錯誤 ctx.loger.info('hello, world')})

          06 is

          在此之前,先看一個 koa 的錯誤處理流程,以下是對 error 進行集中處理,并且標(biāo)識 code 的過程

          app.use(async (ctx, next) => {  try {    await next();  } catch (err) {    let code = 'BAD_REQUEST'    if (err.isAxiosError) {      code = `Axios-${err.code}`    } else if (err instanceof Sequelize.BaseError) {
          } ctx.body = { code } }})

          err.code 處,會編譯出錯,提示 Property 'code' does not exist on type 'Error'.ts(2339)

          此時可以使用 as AxiosError 或者 as any 來避免報錯,不過強制類型轉(zhuǎn)換也不夠友好

          if ((err as AxiosError).isAxiosError) {  code = `Axios-${(err as AxiosError).code}`}

          此時可以使用 is 來判定值的類型

          function isAxiosError (error: any): error is AxiosError {  return error.isAxiosError}
          if (isAxiosError(err)) { code = `Axios-${err.code}`}

          GraphQL 的源碼中,有很多諸如此類的用法,用以標(biāo)識類型

          export function isType(type: any): type is GraphQLType;
          export function isScalarType(type: any): type is GraphQLScalarType;
          export function isObjectType(type: any): type is GraphQLObjectType;
          export function isInterfaceType(type: any): type is GraphQLInterfaceType;

          07 interface & type

          interfacetype 的區(qū)別是什么?可以參考以下 stackoverflow 的問題

          https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types

          一般來說,interfacetype 區(qū)別很小,比如以下兩種寫法差不多

          interface A {  a: number;  b: number;};
          type B = { a: number; b: number;}

          其中 interface 可以如下合并多個,而 type 只能使用 & 類進行連接。

          interface A {    a: number;}
          interface A { b: number;}
          const a: A = { a: 3, b: 4}

          08 Record & Dictionary & Many

          這幾個語法糖是從 lodash 的 types 源碼中學(xué)到的,平時工作中的使用頻率還挺高。

          type Record<K extends keyof any, T> = {    [P in K]: T;};
          interface Dictionary<T> { [index: string]: T;};
          interface NumericDictionary<T> { [index: number]: T;};
          const data:Dictionary<number> = { a: 3, b: 4}

          09 使用 const enum 維護常量表

          相比使用字面量對象維護常量,const enum 可以提供更安全的類型檢查

          // 使用 object 維護常量const TODO_STATUS {  TODO: 'TODO',  DONE: 'DONE',  DOING: 'DOING'}
          // 使用 const enum 維護常量const enum TODO_STATUS {  TODO = 'TODO',  DONE = 'DONE',  DOING = 'DOING'}
          function todos (status: TODO_STATUS): Todo[];
          todos(TODO_STATUS.TODO)

          10 VS Code Tips & Typescript Command

          使用 VS Code 有時會出現(xiàn),使用 tsc 編譯時產(chǎn)生的問題與 vs code 提示的問題不一致

          找到項目右下角的 Typescript 字樣,右側(cè)顯示它的版本號,可以點擊選擇 Use Workspace Version,它表示與項目依賴的 typescript 版本一直。

          或者編輯 .vs-code/settings.json

          {  "typescript.tsdk": "node_modules/typescript/lib"}

          11 Typescript Roadmap

          最后一條也是最重要的一條,翻閱 Roadmap,了解 ts 的一些新的特性與 bug 修復(fù)情況。

          Typescript Roadmap

          參考

          • https://www.typescriptlang.org/docs/handbook/advanced-types.html
          • https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html
          • https://moin.world/2017/06/18/10-typescript-features-you-might-not-know/
          瀏覽 23
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  欧美黑人大群交舔舔舔 | 曰本色黄a大片免费 | 欧美成在线观看 | 日韩一级片网站 | 国产成人精品久久久 |