久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

最近遇見一道不錯的 TS 面試題,分享一下。

這道題有 3 個層次,我們一層層來看。

第一層的要求是這樣的:

實現(xiàn)一個 zip 函數(shù),對兩個數(shù)組的元素按順序兩兩合并,比如輸入 [1,2,3], [4,5,6] 時,返回 [[1,4], [2,5],[3,6]]

這層就是每次各從兩個數(shù)組取一個元素,合并之后放到數(shù)組里,然后繼續(xù)處理下一個,遞歸進(jìn)行這個流程,直到數(shù)組為空即可。

function zip(target, source) {   if (!target.length || !source.length) return [];    const [one, ...rest1] = target;   const [other, ...rest2] = source;    return [[one, other], ...zip(rest1, rest2)]; }
登錄后復(fù)制

結(jié)果是對的:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

第一層還是比較簡單的,然后我們來看第二層要求:

給這個 zip 函數(shù)定義 ts 類型(兩種寫法)

函數(shù)的定義有兩種形式:

直接通過 function 聲明函數(shù):

function func() {}
登錄后復(fù)制

和聲明匿名函數(shù)然后賦值給變量:

const func = () => {}
登錄后復(fù)制

而參數(shù)和返回值的類型都是數(shù)組,只是具體類型不知道,可以寫 unknown[]。

所以兩種函數(shù)類型的定義就是這樣的:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

也是直接 function 聲明函數(shù)類型和 interface 聲明函數(shù)類型然后加到變量類型上兩種。

因為具體元素類型不知道,所以用 unknown。

這里可能會問 any 和 unknown 的區(qū)別:

any 和 unknown 都可以接收任何類型:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但是 any 也可以賦值給任何類型,但 unknown 不行。

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

這里只是用來接收其他類型, 所以 unknown 比any 更合適一些,更安全。

這一層也是比較基礎(chǔ)的 ts 語法,第三層就上了難度了:

用類型編程實現(xiàn)精確的類型提示,比如參數(shù)傳入 [1,2,3], [4,5,6],那返回值的類型要提示出 [[1,4], [2,5],[3,6]]

這里要求返回值類型是精確的,我們就要根據(jù)參數(shù)的類型來動態(tài)生成返回值類型。

也就是這樣:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

聲明兩個類型參數(shù) Target、Source,約束為 unknown[],也就是元素類型任意的數(shù)組類型。

這倆類型參數(shù)分別是傳入的兩個參數(shù)的類型。

返回值通過 Zip 計算得出。

然后要實現(xiàn) Zip 的高級類型:

傳入的類型參數(shù)分別是兩個數(shù)組類型,我們同樣要從中提取出每個元素合并到一起。

提取元素可以用模式匹配的方式:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

所以這個類型就可以這樣定義:

type Zip<One extends unknown[], Other extends unknown[]> =     One extends [infer OneFirst,...infer Rest1]       ? Other extends [infer OtherFirst, ...infer Rest2]         ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]         : []       : [];
登錄后復(fù)制

分別提取兩個數(shù)組的第一個元素,構(gòu)造成新數(shù)組。然后對剩下的數(shù)組遞歸進(jìn)行這樣的處理,直到數(shù)組為空。

這樣就實現(xiàn)了我們想要的高級類型:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但你把它作為返回值加到函數(shù)上會報錯:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

因為聲明函數(shù)的時候都不知道參數(shù)是啥,自然計算不出 Zip<Target, Source> 的值,所以這里會類型不匹配:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

那怎么辦呢?

可以用函數(shù)重載解決:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

ts 支持函數(shù)重載,可以寫多個同名函數(shù)的類型的類型定義,最后寫函數(shù)的實現(xiàn),這樣用到這個函數(shù)的時候會根據(jù)參數(shù)的類型來匹配函數(shù)類型。

我們用了類型編程的那個函數(shù)通過這種方式寫就不會報錯了。

我們使用下看看:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

咋返回值的類型不對呢?

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

其實這時候匹配的函數(shù)類型是對的,只不過推導(dǎo)出的不是字面量類型。

這時候可以加個 as const。

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但是加上 as const 會推導(dǎo)出 readonly [1,2,3]

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

這樣類型就不匹配了,所以要在類型參數(shù)的聲明上也加上 readonly:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但這樣 Zip 函數(shù)的類型又不匹配了。

難道要把所有用到這個類型的地方都加上 readonly 么?

不用,我們 readonly 的修飾去掉不就行了?

Typescript 有內(nèi)置的高級類型 readonly:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

可以把索引類型的每個索引都加上 readonly 修飾:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但沒有提供去掉 readonly 修飾的高級類型,我們可以自己實現(xiàn)一下:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

用映射類型的語法構(gòu)造個新索引類型,加上個 -readonly 就是去掉 readonly 修飾的意思。

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

有的同學(xué)可能問了,數(shù)組類型也是索引類型么?

是,索引類型是聚合多個元素的類型,所以對象、數(shù)組、class 都是。

所以我們把它用在數(shù)組上自然也是可以的:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

(準(zhǔn)確來說叫元組,元組是元素個數(shù)固定的數(shù)組)

那我們只要在傳入 Zip 之前,用 Mutable 去掉 readonly 就可以了:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

再來試一下:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

大功告成!現(xiàn)在返回值的類型就對了。

但還有個問題,如果不是直接傳入字面量,是推導(dǎo)不出字面量類型的,這時候貌似就不對了:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

可我們不都聲明重載類型了么?

如果推導(dǎo)不出字面量類型,應(yīng)該匹配這個呀:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

但實際上它匹配的還是第一個:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

這時候其實只要調(diào)換下兩個函數(shù)類型的順序就可以了:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

這時字面量參數(shù)的情況依然也是對的:

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

為什么呢?

因為重載函數(shù)的類型是從上到下依次匹配,只要匹配到一個就應(yīng)用。

非字面量的情況,類型是 number[],能匹配 unknown[] 的那個類型,所以那個函數(shù)類型生效了。

分享一道不錯的TS面試題(含3層),看看能答到第幾層!

而字面量的情況,推導(dǎo)出的是 readonly [1,2,3],帶有 readonly 所以不匹配 unknown[],繼續(xù)往下匹配,就匹配到了帶有類型參數(shù)的那個函數(shù)類型。

這樣兩種情況就都應(yīng)用了合適的函數(shù)類型。

全部代碼是這樣的:

type Zip<One extends unknown[], Other extends unknown[]> = One extends [   infer OneFirst,   ...infer Rest1 ]   ? Other extends [infer OtherFirst, ...infer Rest2]     ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]     : []   : [];  type Mutable<Obj> = {   -readonly [Key in keyof Obj]: Obj[Key]; };  function zip(target: unknown[], source: unknown[]): unknown[];  function zip<Target extends readonly unknown[], Source extends readonly unknown[]>(   target: Target,   source: Source ): Zip<Mutable<Target>, Mutable<Source>>;  function zip(target: unknown[], source: unknown[]) {   if (!target.length || !source.length) return [];    const [one, ...rest1] = target;   const [other, ...rest2] = source;    return [[one, other], ...zip(rest1, rest2)]; }  const result = zip([1, 2, 3] as const, [4, 5, 6] as const);  const arr1 = [1, 2, 3]; const arr2 = [4, '5', 6];  const result2 = zip(arr1, arr2);
登錄后復(fù)制

ts playground 地址

總結(jié)

今天我們做了一道綜合的 ts 面試題,一共有三層:

第一層實現(xiàn) js 的邏輯,用遞歸或者循環(huán)都能實現(xiàn)。

第二層給函數(shù)加上類型,用 function 聲明類型和 interface 聲明函數(shù)類型兩種方式,參數(shù)和返回值都是 unknown[]。

第三層是用類型編程實現(xiàn)精準(zhǔn)的類型提示,這一層需要拿到參數(shù)的類型,通過提取元素的類型并構(gòu)造出新的數(shù)組類型返回。還要通過函數(shù)重載的方式來聲明類型,并且要注意重載類型的聲明順序。

as const 能夠讓字面量推導(dǎo)出字面量類型,但會帶有 readonly 修飾,可以自己寫映射類型來去掉這個修飾。

其實這也是我們學(xué)習(xí) ts 的順序,我們先要能把 js 邏輯寫出來,然后知道怎么給函數(shù)、class 等加 ts 類型,之后學(xué)習(xí)類型編程,知道怎么動態(tài)生成類型。

其中類型編程是 ts 最難的部分,也是最強大的部分。攻克了這一層,ts 就可以說學(xué)的差不多了。

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
天海翼亚洲一区二区三区| 国产精品大片免费观看| 欧美高清一区| 日本伊人久久| 欧美少妇精品| 亚洲一区二区免费在线观看| 国产精品xxx| 91国语精品自产拍| 国产乱码精品| 在线精品视频在线观看高清| 国产精品一区二区三区av| 99久久激情| 日韩av午夜在线观看| 久久久久99| 另类综合日韩欧美亚洲| 亚洲综合日韩| 日韩大片在线观看| 婷婷亚洲精品| 激情欧美一区二区三区| 欧美激情三区| 日本一不卡视频| 欧美精品自拍| av高清不卡| 欧美日韩一区二区国产| 欧美日韩在线二区| 国产精品成人一区二区网站软件| 亚洲免费黄色| 日韩在线观看不卡| 国产精品magnet| 免费在线观看精品| 日韩久久一区二区三区| 国产精品久久久久久久久久久久久久久 | 欧美在线精品一区| 激情欧美一区二区三区| 久久精品人人| 国产精品多人| 日韩av字幕| 一区二区三区网站| 99精品99| 欧美精品一卡| 亚洲精品一二三区区别| 久久久一二三| 欧美日韩视频免费观看| 国产一区二区三区日韩精品| 久久精品99国产国产精| 日韩欧美美女在线观看| 国产精品腿扒开做爽爽爽挤奶网站| 国产一区二区三区不卡视频网站| 奇米亚洲欧美| 亚洲最新av| 麻豆91精品| 亚洲黄色影院| 在线视频亚洲| 亚洲夜间福利| 欧美va天堂| 亚洲婷婷免费| 不卡一区2区| 午夜欧美在线| 在线亚洲成人| 只有精品亚洲| 亚洲精品第一| 亚洲精品大片| 日本午夜精品视频在线观看| 日韩av黄色在线| 国产精品1区在线| 国产精品99久久免费| 久久精品一区二区国产| 麻豆精品蜜桃视频网站| 国产精品99久久免费观看| 国产精品密蕾丝视频下载| 国产亚洲精品美女久久| 日产欧产美韩系列久久99| 日本视频一区二区| 国产欧美日韩亚洲一区二区三区| 国产欧美日韩精品一区二区免费| 国产精品网在线观看| 久久精品国产福利| 日产精品一区二区| 深夜视频一区二区| 国产一区白浆| 亚洲影院天堂中文av色| 久久激情五月激情| 久久亚洲精精品中文字幕| 国产欧洲在线| 欧美福利在线| 亚洲精品激情| 麻豆视频一区| 久久人人99| 免费在线观看精品| 欧美日韩1区| 色爱综合网欧美| 精品1区2区3区4区| 日韩av不卡在线观看| 精品久久久网| 最新亚洲激情| 91大神在线观看线路一区| 国产精品色婷婷在线观看| 国产精品xx| 老鸭窝毛片一区二区三区| 国产私拍福利精品视频二区| 国产美女高潮在线| 亚洲综合三区| 精品久久不卡| 日韩中文字幕不卡| 精品伊人久久久| 蜜臀91精品国产高清在线观看| 最新国产精品| 麻豆国产一区| 国产亚洲在线观看| 麻豆国产精品777777在线| 九色精品91| 欧美日本不卡| 久久精品主播| 国产免费av国片精品草莓男男| 久久久影院免费| 久久精品 人人爱| 欧美网站在线| 成人一区而且| 日韩精品一区二区三区免费视频 | 久久亚洲资源中文字| 亚洲成人精选| 欧美黄色精品| 亚洲欧洲免费| 亚洲午夜一级| 美腿丝袜在线亚洲一区| 欧美专区18| 日韩视频网站在线观看| 欧美中文高清| 国产亚洲毛片在线| 亚洲综合在线电影| 麻豆精品av| 亚洲+小说+欧美+激情+另类| 99久久视频| 国产aⅴ精品一区二区三区久久| 蜜桃av一区二区三区电影| 丝袜诱惑一区二区| 国产精品久久久久久妇女| 久久国产精品毛片| 亚洲高清毛片| 超碰99在线| 久久wwww| 欧美伊人久久| 美女尤物久久精品| 久久青草久久| 久久精品欧洲| 国产欧美日韩精品高清二区综合区| 国产精品腿扒开做爽爽爽挤奶网站| av资源中文在线天堂| 国产精品一卡| 日本电影久久久| 国产午夜久久| 久久一区二区中文字幕| 久久毛片亚洲| 成人午夜毛片| 精品一区av| 美女视频黄 久久| 国产日韩精品视频一区二区三区| 亚洲一级在线| 伊人久久亚洲影院| 激情婷婷亚洲| 久久蜜桃av| 日韩欧美中文| 亚洲精品成人图区| 久久这里只有精品一区二区| 日韩不卡在线观看日韩不卡视频| 国产午夜久久| 老鸭窝亚洲一区二区三区| 久久av在线| 免费观看日韩电影| 久久夜色精品| 亚洲一区二区网站| 亚洲高清影视| 模特精品在线| 蜜臀精品一区二区三区在线观看 | av资源亚洲| 成人福利视频| 伊伊综合在线| 麻豆网站免费在线观看| 国产精品伦理久久久久久| 国产成人1区| 综合日韩av| 日韩伦理一区| japanese国产精品| 国产视频一区在线观看一区免费| 99成人在线| 亚洲开心激情| 欧美日一区二区在线观看| 欧美有码在线| 麻豆视频观看网址久久| 日韩成人精品一区| 99久久精品网站| 亚洲一区二区毛片| 偷拍亚洲精品| 国产麻豆一区| 国产精品99一区二区三| 98精品视频| 欧美午夜不卡影院在线观看完整版免费| 黄色av一区| 日本高清久久| 成人在线免费观看网站|