偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

聊一聊Typescript 高級(jí)技巧

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

[[415260]]

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

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

01 keyof

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

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

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

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

我們剛開(kāi)始可能會(huì)這么寫(xiě),不過(guò)它有很多缺點(diǎn)

  • 無(wú)法確認(rèn)返回類型:這將損失 ts 最大的類型校驗(yàn)功能
  • 無(wú)法對(duì) key 做約束:可能會(huì)犯拼寫(xiě)錯(cuò)誤的問(wèn)題

這時(shí)可以使用 keyof 來(lái)加強(qiáng) get 函數(shù)的類型功能,有興趣的同學(xué)可以看看 _.get 的 type 標(biāo)記以及實(shí)現(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,可以使用它對(duì)屬性做一些擴(kuò)展, 如實(shí)現(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"

這幾個(gè)類型已內(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

官方文檔對(duì) never 的描述如下

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

結(jié)合 never 與 conditional type 可以推出很多有意思而且實(shí)用的類型,比如 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 的寫(xiě)法

  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 代表取某個(gè)值的 type,可以從以下示例來(lái)展示他們的用法

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

在一個(gè)典型的服務(wù)端項(xiàng)目中,我們經(jīng)常需要把一些工具塞到 context 中,如config,logger,db models, utils 等,此時(shí)就使用到 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.   // 會(huì)報(bào)錯(cuò),因?yàn)?nbsp;logger.ts 中沒(méi)有暴露此方法,可以最大限度的避免拼寫(xiě)錯(cuò)誤 
  12.   ctx.loger.info('hello, world'
  13. }) 

06 is

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

  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 處,會(huì)編譯出錯(cuò),提示 Property 'code' does not exist on type 'Error'.ts(2339)。

此時(shí)可以使用 as AxiosError 或者 as any 來(lái)避免報(bào)錯(cuò),不過(guò)強(qiáng)制類型轉(zhuǎn)換也不夠友好

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

此時(shí)可以使用 is 來(lái)判定值的類型

  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)識(shí)類型

  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 的問(wèn)題

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

一般來(lái)說(shuō),interface 與 type 區(qū)別很小,比如以下兩種寫(xiě)法差不多

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

其中 interface 可以如下合并多個(gè),而 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

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

  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ù)常量表

相比使用字面量對(duì)象維護(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 有時(shí)會(huì)出現(xiàn),使用 tsc 編譯時(shí)產(chǎn)生的問(wèn)題與 vs code 提示的問(wèn)題不一致

找到項(xiàng)目右下角的 Typescript 字樣,右側(cè)顯示它的版本號(hào),可以點(diǎn)擊選擇 Use Workspace Version,它表示與項(xiàng)目依賴的 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)載自微信公眾號(hào)「全棧成長(zhǎng)之路」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系全棧成長(zhǎng)之路公眾號(hào)。

 

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

2024-10-28 21:02:36

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

2022-10-19 15:20:58

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

2022-09-19 16:24:33

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

2018-04-27 09:22:21

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

2023-12-14 11:35:32

.NET泄露模式

2020-05-22 08:16:07

PONGPONXG-PON

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2024-07-24 11:40:33

2018-06-07 13:17:12

契約測(cè)試單元測(cè)試API測(cè)試

2021-02-06 08:34:49

函數(shù)memoize文檔

2023-07-06 13:56:14

微軟Skype

2019-02-13 14:15:59

Linux版本Fedora

2020-10-15 06:56:51

MySQL排序

2022-11-01 08:46:20

責(zé)任鏈模式對(duì)象

2022-08-08 08:25:21

Javajar 文件

2023-05-15 08:38:58

模板方法模式

2018-11-29 09:13:47

CPU中斷控制器

2021-01-29 08:32:21

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

2018-01-10 14:13:04

測(cè)試矩陣API測(cè)試
點(diǎn)贊
收藏

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