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

面試官:說(shuō)說(shuō)你對(duì) TypeScript 中泛型的理解?應(yīng)用場(chǎng)景?

開(kāi)發(fā) 前端
泛型允許我們?cè)趶?qiáng)類(lèi)型程序設(shè)計(jì)語(yǔ)言中編寫(xiě)代碼時(shí)使用一些以后才指定的類(lèi)型,在實(shí)例化時(shí)作為參數(shù)指明這些類(lèi)型 在typescript中,定義函數(shù),接口或者類(lèi)的時(shí)候,不預(yù)先定義好具體的類(lèi)型,而在使用的時(shí)候在指定類(lèi)型的一種特性。

[[422524]]

本文轉(zhuǎn)載自微信公眾號(hào)「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請(qǐng)聯(lián)系JS每日一題公眾號(hào)。

一、是什么

泛型程序設(shè)計(jì)(generic programming)是程序設(shè)計(jì)語(yǔ)言的一種風(fēng)格或范式

泛型允許我們?cè)趶?qiáng)類(lèi)型程序設(shè)計(jì)語(yǔ)言中編寫(xiě)代碼時(shí)使用一些以后才指定的類(lèi)型,在實(shí)例化時(shí)作為參數(shù)指明這些類(lèi)型 在typescript中,定義函數(shù),接口或者類(lèi)的時(shí)候,不預(yù)先定義好具體的類(lèi)型,而在使用的時(shí)候在指定類(lèi)型的一種特性

假設(shè)我們用一個(gè)函數(shù),它可接受一個(gè) number 參數(shù)并返回一個(gè)number 參數(shù),如下寫(xiě)法:

  1. function returnItem (para: number): number { 
  2.     return para 

如果我們打算接受一個(gè) string 類(lèi)型,然后再返回 string類(lèi)型,則如下寫(xiě)法:

  1. function returnItem (para: string): string { 
  2.     return para 

上述兩種編寫(xiě)方式,存在一個(gè)最明顯的問(wèn)題在于,代碼重復(fù)度比較高

雖然可以使用 any類(lèi)型去替代,但這也并不是很好的方案,因?yàn)槲覀兊哪康氖墙邮帐裁搭?lèi)型的參數(shù)返回什么類(lèi)型的參數(shù),即在運(yùn)行時(shí)傳入?yún)?shù)我們才能確定類(lèi)型

這種情況就可以使用泛型,如下所示:

  1. function returnItem<T>(para: T): T { 
  2.     return para 

可以看到,泛型給予開(kāi)發(fā)者創(chuàng)造靈活、可重用代碼的能力

二、使用方式

泛型通過(guò)<>的形式進(jìn)行表述,可以聲明:

  • 函數(shù)
  • 接口
  • 類(lèi)

函數(shù)聲明

聲明函數(shù)的形式如下:

  1. function returnItem<T>(para: T): T { 
  2.     return para 

定義泛型的時(shí)候,可以一次定義「多個(gè)類(lèi)型參數(shù)」,比如我們可以同時(shí)定義泛型 T 和 泛型 U:

  1. function swap<T, U>(tuple: [T, U]): [U, T] { 
  2.     return [tuple[1], tuple[0]]; 
  3.  
  4. swap([7, 'seven']); // ['seven', 7] 

接口聲明

聲明接口的形式如下:

  1. interface ReturnItemFn<T> { 
  2.     (para: T): T 

那么當(dāng)我們想傳入一個(gè)number作為參數(shù)的時(shí)候,就可以這樣聲明函數(shù):

  1. const returnItem: ReturnItemFn<number> = para => para 

類(lèi)聲明

使用泛型聲明類(lèi)的時(shí)候,既可以作用于類(lèi)本身,也可以作用于類(lèi)的成員函數(shù)

下面簡(jiǎn)單實(shí)現(xiàn)一個(gè)元素同類(lèi)型的棧結(jié)構(gòu),如下所示:

  1. class Stack<T> { 
  2.     private arr: T[] = [] 
  3.  
  4.     public push(item: T) { 
  5.         this.arr.push(item) 
  6.     } 
  7.  
  8.     public pop() { 
  9.         this.arr.pop() 
  10.     } 

使用方式如下:

  1. const stack = new Stacn() 

如果上述只能傳遞 string 和 number 類(lèi)型,這時(shí)候就可以使用 的方式猜實(shí)現(xiàn)「約束泛型」,如下所示:

除了上述的形式,泛型更高級(jí)的使用如下:

例如要設(shè)計(jì)一個(gè)函數(shù),這個(gè)函數(shù)接受兩個(gè)參數(shù),一個(gè)參數(shù)為對(duì)象,另一個(gè)參數(shù)為對(duì)象上的屬性,我們通過(guò)這兩個(gè)參數(shù)返回這個(gè)屬性的值

這時(shí)候就設(shè)計(jì)到泛型的索引類(lèi)型和約束類(lèi)型共同實(shí)現(xiàn)

索引類(lèi)型、約束類(lèi)型

索引類(lèi)型 keyof T 把傳入的對(duì)象的屬性類(lèi)型取出生成一個(gè)聯(lián)合類(lèi)型,這里的泛型 U 被約束在這個(gè)聯(lián)合類(lèi)型中,如下所示:

  1. function getValue<T extends object, U extends keyof T>(obj: T, key: U) { 
  2.   return obj[key] // ok 

上述為什么需要使用泛型約束,而不是直接定義第一個(gè)參數(shù)為 object類(lèi)型,是因?yàn)槟J(rèn)情況 object 指的是{},而我們接收的對(duì)象是各種各樣的,一個(gè)泛型來(lái)表示傳入的對(duì)象類(lèi)型,比如 T extends object

使用如下圖所示:

多類(lèi)型約束

例如如下需要實(shí)現(xiàn)兩個(gè)接口的類(lèi)型約束:

  1. interface FirstInterface { 
  2.   doSomething(): number 
  3.  
  4. interface SecondInterface { 
  5.   doSomethingElse(): string 

可以創(chuàng)建一個(gè)接口繼承上述兩個(gè)接口,如下:

  1. interface ChildInterface extends FirstInterface, SecondInterface { 
  2.  

正確使用如下:

  1. class Demo<T extends ChildInterface> { 
  2.   private genericProperty: T 
  3.  
  4.   constructor(genericProperty: T) { 
  5.     this.genericProperty = genericProperty 
  6.   } 
  7.   useT() { 
  8.     this.genericProperty.doSomething() 
  9.     this.genericProperty.doSomethingElse() 
  10.   } 

通過(guò)泛型約束就可以達(dá)到多類(lèi)型約束的目的

三、應(yīng)用場(chǎng)景

通過(guò)上面初步的了解,后述在編寫(xiě) typescript 的時(shí)候,定義函數(shù),接口或者類(lèi)的時(shí)候,不預(yù)先定義好具體的類(lèi)型,而在使用的時(shí)候在指定類(lèi)型的一種特性的時(shí)候,這種情況下就可以使用泛型

靈活的使用泛型定義類(lèi)型,是掌握typescript 必經(jīng)之路

參考文獻(xiàn)

 

https://www.tslang.cn/docs/handbook/generics.html

 

責(zé)任編輯:武曉燕 來(lái)源: JS每日一題
相關(guān)推薦

2021-09-06 10:51:27

TypeScript類(lèi)JavaScript

2021-09-16 07:52:18

算法應(yīng)用場(chǎng)景

2021-09-10 06:50:03

TypeScript裝飾器應(yīng)用

2021-11-10 07:47:49

組合模式場(chǎng)景

2021-11-03 14:10:28

工廠模式場(chǎng)景

2021-08-16 08:33:26

git

2021-11-09 08:51:13

模式命令面試

2021-11-05 07:47:56

代理模式對(duì)象

2021-09-29 07:24:20

場(chǎng)景數(shù)據(jù)

2021-09-28 07:12:09

測(cè)試路徑

2021-11-11 16:37:05

模板模式方法

2021-11-22 23:50:59

責(zé)任鏈模式場(chǎng)景

2021-10-09 10:25:41

排序應(yīng)用場(chǎng)景

2021-10-08 09:59:32

冒泡排序場(chǎng)景

2021-10-13 18:01:33

快速排序場(chǎng)景

2021-11-04 06:58:32

策略模式面試

2021-05-31 10:35:34

TCPWebSocket協(xié)議

2021-10-18 07:51:39

回溯算法面試

2021-10-12 07:15:02

歸并排序場(chǎng)景

2021-10-11 09:38:41

開(kāi)源
點(diǎn)贊
收藏

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