成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

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

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

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

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

第一層的要求是這樣的:

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

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

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

結果是對的:

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

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

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

函數的定義有兩種形式:

直接通過 function 聲明函數:

function func() {}
登錄后復制

和聲明匿名函數然后賦值給變量:

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

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

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

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

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

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

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

這里可能會問 any 和 unknown 的區別:

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

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

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

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

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

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

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

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

這里要求返回值類型是精確的,我們就要根據參數的類型來動態生成返回值類型。

也就是這樣:

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

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

這倆類型參數分別是傳入的兩個參數的類型。

返回值通過 Zip 計算得出。

然后要實現 Zip 的高級類型:

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

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

分享一道不錯的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>]         : []       : [];
登錄后復制

分別提取兩個數組的第一個元素,構造成新數組。然后對剩下的數組遞歸進行這樣的處理,直到數組為空。

這樣就實現了我們想要的高級類型:

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

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

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

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

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

那怎么辦呢?

可以用函數重載解決:

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

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

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

我們使用下看看:

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

咋返回值的類型不對呢?

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

其實這時候匹配的函數類型是對的,只不過推導出的不是字面量類型。

這時候可以加個 as const。

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

但是加上 as const 會推導出 readonly [1,2,3]

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

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

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

但這樣 Zip 函數的類型又不匹配了。

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

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

Typescript 有內置的高級類型 readonly:

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

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

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

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

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

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

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

有的同學可能問了,數組類型也是索引類型么?

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

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

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

(準確來說叫元組,元組是元素個數固定的數組)

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

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

再來試一下:

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

大功告成!現在返回值的類型就對了。

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

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

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

如果推導不出字面量類型,應該匹配這個呀:

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

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

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

這時候其實只要調換下兩個函數類型的順序就可以了:

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

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

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

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

為什么呢?

因為重載函數的類型是從上到下依次匹配,只要匹配到一個就應用。

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

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

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

這樣兩種情況就都應用了合適的函數類型。

全部代碼是這樣的:

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);
登錄后復制

ts playground 地址

總結

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

第一層實現 js 的邏輯,用遞歸或者循環都能實現。

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

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

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

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

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

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
成人免费视频无码专区| √天堂8资源中文在线| 日本熟妇在线一区二区三区| 当着老公的面被别人欺负该怎么办| 尤物YW午夜国产精品视频| 亚洲AV无码成H人动漫网站| 日产无人区一线二线三线小说| 美女高潮无遮挡免费视频| 精品国产乱码久久久久软件 | 国精产品一区一区三区| 大BBW大BBW大BBW| 国产精品毛片无码| 国产成人AV综合亚洲色欲| 成熟丰满熟妇AV无码| 苍井空浴缸大战猛男120分钟| 7777精品久久久大香线蕉| 在线永久无码不卡AV| 野花高清在线观看免费 | 日韩欧洲亚洲SUV| 欧美一性一乱一交一视频C| 蜜桃AV麻豆AV天美AV| 久久久亚洲欧洲日产国产成人无码| 精品无码久久久久久久久久| 狠狠色丁香久久婷婷综合_中| 国产精品福利自产拍在线观看| 丰满妇女强高潮18ⅩXXX小说| 成人国产精品一区二区网站免费| 国产AV大学生第一次破| 国产成人精品综合久久久久性色| IPHONE欧美高级| 一区二区三区国产精品保安| 男男野战爆了我的菊BL| 久久强奷乱码老熟女| 久久大香香蕉国产拍国| 精品少妇无码AV在线播放| 女人被躁到高潮嗷嗷叫小说百度| 欧美A级情欲片在线观看免费 | 永久免费的啪啪免费网址| 一本大道AV伊人久久综合| 影音先锋女人AV女色资源| 成人美女黄网站18禁免费| 精品JAVAPARSER乱偷| 精品无码国产自产在线观看水浒传 | 热99RE久久免费视精品频| 欧美性猛交XXXX乱大交蜜桃| 无码人妻在线视频| 亚洲AV无码成H人在线观看 | 疯狂做受XXXX高潮不断| 国产成年女人特黄特色毛片免| 久爱WWW成人网免费视频| 老司机精品成人无码AV| 欧美 日韩 国产 成人 在线观| 天堂中文在线最新版地址| 午夜亚洲AⅤ无码高潮片在线观看 午夜亚洲AⅤ无码高潮片苍井空 | 国产精品毛片AV一区二区三区| 美女裸体无遮挡永久免费视频AP | 无码人妻精品一区二区三区免费 | 日本在线视频WWW鲁啊鲁| 亚洲日韩AV无码一区二区三区| 亚洲性色AV片在线观看网址 | 妺妺晚上扒我内裤吃我精子H| 欧美人与禽Z0ZO牲伦交| 色噜噜影院狠狠狠噜| 亚洲6080YY久久无码产自国| 亚洲熟妇无码乱子AV电影| 99久热RE在线精品99RE| 粉嫩一区二区三区性色AV| 久久天天躁狠狠躁夜夜免费观看| 撕掉她的衣服吮的双乳游戏| 亚洲SSS整片AV在线播放| 在线播放无码后入内射少妇| 被老外添嫩苞添高潮NP电影| 国产精品久久久久久久久久久不卡 | 麻豆国产97在线 | 欧洲| 欧洲S码亚洲M码精品一区| 亚洲成AV人最新无码| 中文字幕熟妇人妻在线视频| 成人无码精品一区二区三区亚洲区| 国产精品一区二区AV麻豆| 久久久久久久女国产乱让韩| 人妻人人澡人人添人人爽人人玩| 无码精品人成人片在线观看| 亚洲综合色在线观看一区二区 | 为什么穿裙子方便打野| 亚洲日韩AV无码一区二区三区| 国产超碰AV人人做人人爽| 欧美性爱XXXX黑人| 午夜影视免费观看2023| 波多野结衣在线观看AV| 国产在线内射婷婷| 欧美丰满熟妇BBBBBB百度 | 欧美黑人暴力深喉囗交| 夜夜高潮次次欢爽AV女视频| 韩漫漫画无遮挡免费| 欧美多人片高潮野外做片黑人 | 香蕉尹人综合在线观看| 疯狂做受ⅩⅩⅩⅩ高潮高清视频| 欧美极品少妇XXXXⅩ| 在线 | 一区二区三区四区| 精品一区二区久久久久久久网站| 无人区一码卡二卡三乱码 | 亚洲国产精品一区二区成人片不卡 | 国产69精品久久久久99尤物| 国产精品国产AV片国产| 精二和精三的区别| 无码动漫性爽XO视频在线| 成人免费视频一区二区| 女人为啥摸几下就让进了| 孕妇泬出白浆18P| 久久精品国产网红主播| 欧洲亚洲1卡二卡三卡2021| 亚洲AⅤ成人精品无码| 快拨出天我是你母亲| 欧美A级情欲片在线观看免费| 野花日本大全免费观看2019| 精品成人一区二区三区四区| 亚洲AV无码成人精品区瑜伽裤| JAPANESEⅩⅩⅩHD日本| 奶头被民工们吸得又红又肿怎么办| 一边做一边喷17P| 久久久久亚洲AV无码专区网站| 亚洲人成精品久久久久| 国产A在亚洲线播放| 色YEYE香蕉凹凸视频在线观看| 被黑人猛男强伦姧人妻完整版| 琪琪777午夜理论片在线观看播| AV成人羞羞漫画永久入口| 精品人妻少妇嫩草Av无码专区| 搡老女人野外老熟妇AAA| 成人无码免费视频在线观看网址| 日本XXXX裸体XXXX免费| 杂乱小说2第400部| 老外免费CSGO交易网站有哪些 | 真人荫道口图片100张| 乱中年女人伦AV一区二区| 中国 韩国 日本 免费看| 妺妺窝人体色777777| AV无码一区二区大桥久未| 欧美日韩人妻精品一区在线 | 久久天堂无码AV网站| 亚洲日韩一区二区三区| 久久久久成人精品无码| 幼儿稀缺区超清幼儿做的网站| 免费国产VA在线观看中文字| 深灬深灬深灬深灬一点| 6080电影网站| 久久精品国产亚洲AV日韩| 亚洲小说区图片区另类春色| 久久久久久精品免费免费WEⅠ| 与上司出轨的人妻| 欧美1卡2卡3卡4卡免费高清| 被公牛日到了高潮| 天堂√最新版中文在线天堂| www.内射孕妇网站入口| 麻花传媒MV在线播放高清MBA| 97久久精品亚洲中文字幕无码| 漂亮人妻沦陷精油按摩| 夫妇交换聚会群4P疯狂大战| 午夜.DJ高清免费观看视频| 狠狠色丁香五月综合婷婷| 亚洲中文无码MV| 精品无码久久久久久久久水蜜桃| 亚洲一区精品无码| 男人激烈吮乳吃奶视频免费| 亚洲国模337P人艺体艺术| 久久亚洲人成网站| 亚洲日韩VA无码中文字幕 | 夜夜添夜夜添夜夜摸夜夜摸| 欧美人与禽Z0ZO牲伦交| 国产SUV精品一区二区五| 亚洲AV永久无码精品无码四虎| 国产精品麻豆欧美日韩WW| 亚洲精品无码午夜福利理论片| 国产色婷婷精品综合在线| 天天摸天天透天天添| 激情视频传媒一区二区| 亚洲国产AⅤ成人精品无吗| 国产真实乱XXXⅩ| 伊伊人成亚洲综合人网香| 人妻在线日韩免费视频| 99久RE热视频这里只有精品6| 国产又粗又猛又爽又黄的视频免费黑人了| 小雪好湿用力啊进来轻点 | 黑人玩弄人妻一区二区三区| 国产95在线 | 亚洲| 无码人妻丰满熟妇一区二区三区| 精品人妻一区二区三区四区 | 老熟女@TUBEUMTV| 宝贝乖女你的奶真大水真多| 亚州中文字幕午夜福利电影| 国产成人精品亚洲精品| 亚洲欧美日本韩国| 人妻少妇伦在线无码专区视频| 国产啪精品视频网站免费| 亚洲av成人一区| 麻豆星空传媒果冻传媒大象 | 99国产精品99久久久久久| 欧美日韩一区精品视频一区二| 英语老师的小兔子好大好软水| 色欲av无码爆乳亚洲区一二|