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

泛型,很多人因它放棄學(xué)習(xí)TypeScript?

開(kāi)發(fā) 前端
直到大學(xué)畢業(yè)我依舊沒(méi)有理解泛型的概念,可能你和我一樣覺(jué)得泛型很難,下面我會(huì)分享我的理解,希望對(duì)你有所幫助。

 

1、ts的泛型很難嗎?

如果你:

  1.  剛開(kāi)始學(xué)ts
  2.  剛開(kāi)始接觸泛型
  3.  正在掙扎得學(xué)習(xí)ts的泛型

看到以下代碼有沒(méi)有很疑惑? 

  1. function makePair<  
  2.   F extends number | string,  
  3.   S extends boolean | F  
  4. >() 

Java是和typescript一樣支持泛型的,當(dāng)我在大學(xué)開(kāi)始學(xué)習(xí)Java的時(shí)候,我還是一個(gè)菜鳥(niǎo)碼農(nóng),遇到難點(diǎn)(比如泛型)就直接跳過(guò),能學(xué)多少學(xué)多少,回寢室就LOL開(kāi)黑。直到大學(xué)畢業(yè)我依舊沒(méi)有理解泛型的概念,可能你和我一樣覺(jué)得泛型很難,下面我會(huì)分享我的理解,希望對(duì)你有所幫助。

2、一起來(lái)看一下makeState()這個(gè)函數(shù)

首先,我寫(xiě)了makeState這個(gè)函數(shù),我們會(huì)用這個(gè)函數(shù)來(lái)討論泛型 

  1. function makeState() {  
  2.   let state: number  
  3.   function getState() {  
  4.     return state  
  5.   }  
  6.   function setState(x: number) {  
  7.     state = x  
  8.   }  
  9.   return { getState, setState }  

當(dāng)你運(yùn)行這個(gè)函數(shù),我們會(huì)得到getState() 和 setState()這兩個(gè)函數(shù)。

讓我們來(lái)試一下,下面這段代碼會(huì)打印出什么 

  1. const { getState, setState } = makeState()  
  2. setState(1)  
  3. console.log(getState())  
  4. setState(2)  
  5. console.log(getState())    
  1.  

會(huì)打印出1和2,沒(méi)那么難對(duì)吧?

Note: 如果你正在使用react,你可能會(huì)發(fā)覺(jué),makeState()和鉤子函數(shù)useState()很像。這里也涉及到了閉包和ES6的解構(gòu)賦值 

3、我們傳入字符串會(huì)如何?

我們把剛才給setState的入?yún)?和2替換成字符串'foo'會(huì)輸出什么呢? 

  1. const { getState, setState } = makeState()  
  2. setState('foo')  
  3. console.log(getState())  
  1. Argument of type '"foo"' is not assignable to parameter of type 'number'. 

會(huì)編譯失敗,因?yàn)閟etState()需要的參數(shù)類型是number

我們可以用以下方法解決這個(gè)問(wèn)題 

  1. function makeState() {  
  2.   // Change to string  
  3.   let state: string  
  4.   function getState() {  
  5.     return state  
  6.   }  
  7.   // Accepts a string  
  8.   function setState(x: string) {  
  9.     state = x  
  10.   }  
  11.   return { getState, setState }  
  12.  
  1. const { getState, setState } = makeState()  
  2. setState('foo')  
  3. console.log(getState()) 
  1. foo 

4、挑戰(zhàn):獲取兩個(gè)不同類型的state

我們能不能修改makeState()這個(gè)函數(shù),來(lái)輸出兩個(gè)不同類型的state,比如一個(gè)是字符串,一個(gè)是數(shù)字。

以下代碼簡(jiǎn)略得表示我想表達(dá)的意思: 

  1. // One that only allows numbers, and…  
  2. const numState = makeState()  
  3. numState.setState(1)  
  4. console.log(numState.getState()) // 1  
  5. // The other that only allows strings.  
  6. const strState = makeState()  
  7. strState.setState('foo')  
  8. console.log(strState.getState()) // foo 

要達(dá)到以上效果,我們可能需要?jiǎng)?chuàng)建兩個(gè)內(nèi)部不一樣的makeState(),一個(gè)state的類型是數(shù)字,一個(gè)是字符串。

怎么用才能只寫(xiě)一個(gè)來(lái)實(shí)現(xiàn)呢?

5、實(shí)驗(yàn)一:設(shè)置多個(gè)類型

這是我們的第一個(gè)嘗試: 

  1. function makeState() {  
  2.   let state: number | string  
  3.   function getState() {  
  4.     return state  
  5.   }  
  6.   function setState(x: number | string) {  
  7.     state = x  
  8.   }  
  9.   return { getState, setState }  
  10.  
  1. const numAndStrState = makeState()  
  2. //數(shù)字  
  3. numAndStrState.setState(1)  
  4. console.log(numAndStrState.getState())  
  5. //字符串  
  6. numAndStrState.setState('foo')  
  7. console.log(numAndStrState.getState())    
  1.  
  2. foo 

結(jié)果看上去我們貌似成功了,但是這并不是我真實(shí)想要的,我們真正要實(shí)現(xiàn)的是只能輸出數(shù)字state和只能輸出字符串state。

numAndStrState是既能輸出數(shù)字類型,又能輸出字符串類型

6、實(shí)現(xiàn)二:使用泛型

接下來(lái)我們的泛型要登場(chǎng)了: 

  1. function makeState<S>() {  
  2.   let state: S  
  3.   function getState() {  
  4.     return state  
  5.   }  
  6.   function setState(x: S) {  
  7.     state = x  
  8.   }  
  9.   return { getState, setState }  

makeState() 被定義成 makeState<S>(),你可以把<S>當(dāng)作函數(shù)參數(shù),但它傳入的不是值,而是類型。

比如你可以傳入數(shù)字類型: 

  1. makeState<number>() 

在makeSate()這個(gè)函數(shù)內(nèi)部state會(huì)變成數(shù)字類型 

  1. let state: S // <- number  
  2. function setState(x: S /* <- number */) {  
  3.   state = x  

這樣就實(shí)現(xiàn)了只能輸出數(shù)字state 

  1. // Creates a number-only state  
  2. const numState = makeState<number>()  
  3. numState.setState(1)  
  4. console.log(numState.getState())  
  5. // numState.setState('foo') 輸入字符串foo會(huì)報(bào)錯(cuò) 

同理我們也可以實(shí)現(xiàn)只能輸出字符串state 

  1. // Creates a string-only state  
  2. const strState = makeState<string>()  
  3. strState.setState('foo')  
  4. console.log(strState.getState())  
  5. // strState.setState(1) 輸入數(shù)字1會(huì)報(bào)錯(cuò) 

Note: 我們把makeState<S>()稱作泛型函數(shù),就是一個(gè)普通的函數(shù)支持類型參數(shù)的傳入

你可能會(huì)疑惑為什么類型參數(shù)是S, 其實(shí)隨便什么都可以,但是通常來(lái)說(shuō)我們會(huì)用一個(gè)變量的第一個(gè)字母的大寫(xiě)來(lái)代表這個(gè)變量的類型:

  •   T(for“T”ype)
  •   E(for“E”lement)
  •   K(for“K”ey)
  •   V(for“V”alue)

7、泛型的類型范圍限制

目前,在我們改進(jìn)下的makeState()實(shí)現(xiàn)了只能輸出數(shù)字state和只能輸出字符串state。但是它也能實(shí)現(xiàn)輸出布爾值。 

  1. // Creates a boolean-only state  
  2. const boolState = makeState<boolean>()  
  3. boolState.setState(true)  
  4. console.log(boolState.getState()) 

問(wèn)題:那么我們要如何限制它就只能輸入輸出number和string類型呢?

方法:聲明makeState()這個(gè)函數(shù)時(shí),把類型參數(shù)<S>變?yōu)?lt;S extends number | string>,這樣就只能輸入number或者string類型了 

  1. function makeState<S extends number | string>() {  
  2.   let state: S  
  3.   function getState() {  
  4.     return state  
  5.   }  
  6.   function setState(x: S) {  
  7.     state = x  
  8.   }  
  9.   return { getState, setState }  
  10.  
  11. // 如果我傳入boolean類型  
  12. const boolState = makeState<boolean>()  
  1. Type 'boolean' does not satisfy the constraint 'string | number'. 

8、泛型的默認(rèn)類型

現(xiàn)在每次調(diào)用makeState()時(shí),我們可以任意傳入<number> 或<string>類型,那怎么設(shè)置一個(gè)默認(rèn)類型呢?

比如讓下面兩個(gè)語(yǔ)句起到相同的作用: 

  1. const numState1 = makeState()  
  2. const numState2 = makeState<number>() 

其實(shí)和給函數(shù)參數(shù)設(shè)置默認(rèn)值一樣: 

  1. function makeState<S extends number | string = number>() 

這樣,變量state默認(rèn)類型就是number了 

  1. const numState = makeState()  
  2. numState.setState(1)  
  3. console.log(numState.getState())  

9、總結(jié)

泛型其實(shí)可以當(dāng)作普通函數(shù)在聲明時(shí)的一個(gè)參數(shù),這個(gè)參數(shù)代表類型。

我們可以給函數(shù)值參數(shù)設(shè)置默認(rèn)值,

也可以通過(guò)typescipt的泛型給函數(shù)類型參數(shù)設(shè)置默認(rèn)值。 

  1. function regularFunc(x = 2 
  2. regularFunc()  
  1. function genericFunc<TT = number>()  
  2. genericFunc()  

 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2024-06-13 10:37:30

2025-02-21 08:48:16

Typescript內(nèi)置聯(lián)合類型

2024-09-12 08:32:42

2021-01-30 11:42:53

迭代器代碼元素

2021-02-22 13:14:00

計(jì)算機(jī)編程技術(shù)

2022-02-06 00:07:19

互聯(lián)網(wǎng)失業(yè)職業(yè)

2018-02-13 14:48:17

戴爾

2022-07-06 10:33:39

技術(shù)債務(wù)CIO

2017-12-13 15:57:12

2021-06-24 09:08:34

Java代碼泛型

2019-08-21 08:24:34

技術(shù)過(guò)濾器代碼

2021-12-14 07:40:08

前端

2014-05-09 15:29:21

2020-06-29 08:28:36

v-for 解構(gòu)函數(shù)

2020-11-16 11:24:00

Spring AOP數(shù)據(jù)庫(kù)

2021-01-15 05:39:13

HashMapHashTableTreeMap

2020-06-08 19:16:52

大數(shù)據(jù)IT技術(shù)

2019-08-08 16:00:08

HTTPGETPOST

2021-09-21 10:33:56

人工智能科學(xué)技術(shù)

2022-01-05 23:34:02

顯示器濾藍(lán)光LED
點(diǎn)贊
收藏

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