自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊一聊Typescript 高級技巧

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

[[415260]]

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

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

01 keyof

keyof 與 Object.keys 略有相似,只不過 keyof 取 interface 的鍵。

  1. interface Point { 
  2.     x: number; 
  3.     y: number; 
  4.  
  5. // type keys = "x" | "y" 
  6. type keys = keyof Point; 

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

  1. const data = { 
  2.   a: 3, 
  3.   hello: 'world' 
  4.  
  5. function get(o: object, name: string) { 
  6.   return o[name

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

  • 無法確認(rèn)返回類型:這將損失 ts 最大的類型校驗功能
  • 無法對 key 做約束:可能會犯拼寫錯誤的問題

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

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

02 Required & Partial & Pick

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

  1. type Partial<T> = { 
  2.   [P in keyof T]?: T[P]; 
  3. }; 
  4.  
  5. type Required<T> = { 
  6.   [P in keyof T]-?: T[P]; 
  7. }; 
  8.  
  9. type Pick<T, K extends keyof T> = { 
  10.   [P in K]: T[P]; 
  11. }; 
  12.  
  13. interface User { 
  14.   id: number; 
  15.   age: number; 
  16.   name: string; 
  17. }; 
  18.  
  19. // 相當(dāng)于: type PartialUser = { id?: number; age?: number; name?: string; } 
  20. type PartialUser = Partial<User
  21.  
  22. // 相當(dāng)于: type PickUser = { id: number; age: number; } 
  23. type PickUser = Pick<User"id" | "age"

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

03 Condition Type

類似于 js 中的 ?: 運(yùn)算符,可以使用它擴(kuò)展一些基本類型

  1. T extends U ? X : Y 
  2.  
  3. type isTrue<T> = T extends true ? true : false 
  4. // 相當(dāng)于 type t = false 
  5. type t = isTrue<number> 
  6.  
  7. // 相當(dāng)于 type t = false 
  8. type t1 = isTrue<false

04 never & Exclude & Omit

官方文檔對 never 的描述如下

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

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

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

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

  1. type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; 
  2.  
  3. interface User { 
  4.   id: number; 
  5.   age: number; 
  6.   name: string; 
  7. }; 
  8.  
  9. // 相當(dāng)于: type PickUser = { age: number; name: string; } 
  10. type OmitUser = Omit<User"id"

05 typeof

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

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

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

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

06 is

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

  1. app.use(async (ctx, next) => { 
  2.   try { 
  3.     await next(); 
  4.   } catch (err) { 
  5.     let code = 'BAD_REQUEST' 
  6.     if (err.isAxiosError) { 
  7.       code = `Axios-${err.code}` 
  8.     } else if (err instanceof Sequelize.BaseError) { 
  9.  
  10.     } 
  11.     ctx.body = { 
  12.       code 
  13.     } 
  14.   } 
  15. }) 

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

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

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

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

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

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

  1. export function isType(type: any): type is GraphQLType; 
  2.  
  3. export function isScalarType(type: any): type is GraphQLScalarType; 
  4.  
  5. export function isObjectType(type: any): type is GraphQLObjectType; 
  6.  
  7. export function isInterfaceType(type: any): type is GraphQLInterfaceType; 

07 interface & type

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

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

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

  1. interface A { 
  2.   a: number; 
  3.   b: number; 
  4. }; 
  5.  
  6. type B = { 
  7.   a: number; 
  8.   b: number; 

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

  1. interface A { 
  2.     a: number; 
  3.  
  4. interface A { 
  5.     b: number; 
  6.  
  7. const a: A = { 
  8.     a: 3, 
  9.     b: 4 

08 Record & Dictionary & Many

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

  1. type Record<K extends keyof any, T> = { 
  2.     [P in K]: T; 
  3. }; 
  4.  
  5. interface Dictionary<T> { 
  6.   [index: string]: T; 
  7. }; 
  8.  
  9. interface NumericDictionary<T> { 
  10.   [index: number]: T; 
  11. }; 
  12.  
  13. const data:Dictionary<number> = { 
  14.   a: 3, 
  15.   b: 4 

09 使用 const enum 維護(hù)常量表

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

  1. // 使用 object 維護(hù)常量 
  2. const TODO_STATUS { 
  3.   TODO: 'TODO'
  4.   DONE: 'DONE'
  5.   DOING: 'DOING' 
  1. // 使用 const enum 維護(hù)常量 
  2. const enum TODO_STATUS { 
  3.   TODO = 'TODO'
  4.   DONE = 'DONE'
  5.   DOING = 'DOING' 
  6.  
  7. function todos (status: TODO_STATUS): Todo[]; 
  8.  
  9. 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

  1.   "typescript.tsdk""node_modules/typescript/lib" 

11 Typescript Roadmap

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

參考

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/

本文轉(zhuǎn)載自微信公眾號「全棧成長之路」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系全棧成長之路公眾號。

 

責(zé)任編輯:武曉燕 來源: 全棧成長之路
相關(guān)推薦

2024-10-28 21:02:36

消息框應(yīng)用程序

2022-09-19 16:24:33

數(shù)據(jù)可視化Matplotlib工具

2022-10-19 15:20:58

pandas數(shù)據(jù)處理庫技巧

2018-04-27 09:22:21

數(shù)據(jù)存儲技巧

2023-12-14 11:35:32

.NET泄露模式

2023-09-22 17:36:37

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2024-07-24 11:40:33

2018-06-07 13:17:12

契約測試單元測試API測試

2022-08-08 08:25:21

Javajar 文件

2018-11-29 09:13:47

CPU中斷控制器

2019-02-13 14:15:59

Linux版本Fedora

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2021-02-06 08:34:49

函數(shù)memoize文檔

2023-05-15 08:38:58

模板方法模式

2022-11-01 08:46:20

責(zé)任鏈模式對象

2023-07-06 13:56:14

微軟Skype

2020-10-15 06:56:51

MySQL排序

2020-09-08 06:54:29

Java Gradle語言
點贊
收藏

51CTO技術(shù)棧公眾號