成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院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號
被黑人巨茎日出白浆的少妇| 爆乳熟妇一区二区三区| FREEZEFRAME丰满少妇| 啊灬啊灬啊灬快灬高潮了老| 吃奶呻吟打开双腿做受在线视频| 国产成人综合五月天久久| 国内精品久久久久久99蜜桃| 久久久久久A亚洲欧洲AⅤ| 美女与野兽在线观看| 人人妻人人爽人人人少妇| 婷婷色婷婷开心五月四房播播| 亚洲AV色香蕉一区二区蜜桃小说 | 国产SUV精二区69| 果冻传媒AⅤ毛片无码| 久久久久久久久久精品电影| 欧美一进一出抽搐大尺度视频| 少妇把腿扒开让我添69动态图| 亚洲AV成人片无码网站| 影音先锋AV天堂| 成交人性成交视频| 国产午夜精品免费一区二区三区 | 无码天堂亚洲国产AV麻豆| 亚洲欧美综合区丁香五月小说 | 艳妇乳肉豪妇荡乳ⅩXXO电影| 18无码粉嫩小泬无套在线观看| 短篇公交车高H肉辣全集目录| 好爽好大再深点高H免费观看| 迈开腿让我尝一下你的味道一| 色噜噜狠狠色综合无码AV天堂| 亚洲VA中文字幕无码久久| 18禁动漫无码无遮挡免费看| 丰满岳跪趴高撅肥臀| 精品亚洲国产成人AV不卡| 欧美黑人巨大XXXX黑人猛| 无码夫の前で人妻を犯す中字| 亚洲中文字幕在线第六区| 波多野结衣AV大全| 黑人异族巨大巨大巨粗| 欧美人与动牲交A欧美精品Z| 无人区一码二码三码四码| 中文无码熟妇人妻AV在线 | chineSe老女人老熟妇hd| 国产毛片一二区三区四区| 免费无码成人AV在线播放| 天天做AV天天爱天天爽| 中国丰满人妻VIDEOSHD| 国产成人综合色在线观看网站| 噜噜噜亚洲色成人网站| 天堂资源中文WWW| 宅男666在线永久免费观看| 国产成人精品综合久久久| 狂猛欧美激情性XXXX大豆行情| 色欲网久久久久久久久久久久久久 | 亚洲成亚洲乱码一二三四区软件| MD豆传媒APP网址| 精品国产乱码久久久久久小说| 清纯校花挨脔日常H惩罚视频| 亚洲国产精品久久久久久| 本免费AV无码专区一区| 精品人妻一区二区三区三区换着玩 | 成人全部免费的A毛片在线看| 久久久精品人妻一区二区三区蜜桃| 熟妇av一区二区| 2022国产成人无码AⅤ片| 国产最大成人亚洲精品| 日本黄色免费在线观看| 一二三四视频社区| 国产肉体XXXX裸体XXXX| 人妻 中文无码 中出| 亚洲综合小说区图片区| 国产乱妇乱子在线播放视频| 人妻少妇精品无码专区二区| 一本到高清视频在线观看丶| 国产精品日日摸夜夜添夜夜添| 欧美一区在线视频| 一边喂奶一边挨CAO| 国产精品亚洲专区无码蜜芽 | 西方37大但人文艺术A管77| www.av在线.com| 久久人妻少妇嫩草AV蜜桃| 小寡妇好紧进去了好大看视频| YOUJIZZ中国熟女| 开心亚洲五月丁香五月| 亚洲AV无码精品色午夜| 公交车被CAO得合不拢腿视频| 女人扒开腿让男人狂桶30分钟| 亚洲欧洲日产国码无码| 国产精品亚洲А∨天堂免| 日本熟妇XXⅩ浓密黑毛HD| 18禁裸男晨勃露J毛免费观看| 精品国产成人A区在线观看| 乌克兰性猛交ⅩXXX乱大交| 差差差无掩盖30分钟79集| 妺妺窝人体色WWW聚色窝丿| 亚洲人成人网站色www小说| 国产精品亚洲专区无码蜜芽| 日日噜噜夜夜狠狠视频| JAPANESEHD日本乱厨房| 麻豆果冻视频传媒APP下载| 亚洲国产另类久久久精品小说| 国产精品无码A∨麻豆| 日日噜噜夜夜狠狠久久蜜桃| GOGO少妇无码肉肉视频| 免费看B站直播APP下载| 亚洲精品无码一区二区AⅤ污美国| 国产精品无码久久综合网| 色综合亚洲一区二区小说性色AⅤ 色综合天天综合网天天小说 | 我半夜摸妺妺的奶摸到高潮| 方辰苏婉儿是哪本小说的主角| 欧美一区精品视频一区二区| 7777奇米四色眼影| 毛片亚洲AV无码精品国产午夜| 亚洲性色AV日韩在线观看| 精品第一国产综合精品蜜芽 | 韩国亚洲精品a在线无码| 羞羞漫画_成人漫画_成人专用 | 亚洲AⅤ在线无码播放毛片一线天 亚洲AⅤ优女AV综合久久久 | 国产成人精品免费视频大全软件 | 国产AV无码专区国产乱码| 上司侵犯部下的人妻| 成人网站亚洲二区乱码| 日产中文字幕在线精品一区| 车内挺进尤物少妇紧窄| 日产精品卡2卡三卡乱码网址| 锕锕锕锕锕锕锕好疼免费视频| 强行糟蹋人妻HD中文字幕| FREE性玩弄妇女HD| 拍摄AV现场失控高潮数次| H工口全彩里番库18禁无遮挡| 女人露P毛视频·WWW| AⅤ一区二区三区无卡无码| 欧美18VIDEOSEX性极品| ASIANMATURE老熟妇女| 欧洲乱码一卡2卡三卡4卡高清| JAPANESE熟女熟妇多毛毛| 人妻人人做人妻人人添| 成人精品视频一区二区不卡| 日日噜噜夜夜狠狠久久无码区| 国产AV无码日韩AV无码网站| 午夜成人亚洲理论片在线观看 | 国产成人AⅤ片在线观看| 天堂いっしょにしよ在线| 国产品无码一区二区三区在线| 亚洲AV成人无码一区在线观看| 精产国品一二三产区M553麻豆| 亚洲日韩AV无码| 另类老妇性BBWBBW| 99久久精品国产一区二区三区| 人妻系列AV无码专区| 国产SUV精品一区二区五| 小辣椒AV福利在线网站| 精品国产午夜肉伦伦影院| 伊人久久大香线蕉综合5G| 女人与公拘交酡ZOZO| 成 人 黄 色 网 站 18| 推拿完整版中文字幕| 国语自产偷拍精品视频偷拍| 亚洲中文字幕无码一久久区| 女人18毛片A级毛片视频| 草草永久地址发布页①| 无码A级毛片视频| 精品少妇人妻AV无码专区| 自拍日韩亚洲一区在线| 日本高清在线视频WWW色| 国产精品盗摄!偷窥盗摄| 亚洲丰满少妇多毛大隂户| 老子影院午夜精品无码| 拔萝卜打牌不盖被子| 无码国内精品人妻少妇蜜桃视频| 精东传媒VS天美传媒在线老牛| 在线观看成人网站| 人人鲁人人莫人人爱精品| 国产精品嫩草影院AV| 亚洲熟妇丰满多毛XXXX| 欧美〇〇无码黑人大战野结衣| 丰满浓毛的大隂户自慰| 亚洲VA在线∨A天堂VA欧美V| 妺妺窝人体色www在线下载人| 丁香激情五月中文字幕亚洲| 亚洲AV无码国产永久播放蜜芽 | 精品噜噜噜噜久久久久久久久| 主人调教下贱的烂货| 少妇人妻偷人精品一区二区| 精品久久综合1区2区3区激情| 99精品人妻无码专区在线视频区 | 人妻人人做人碰人人添青青| 国产麻传媒精品国产AV| 在线|国产精品女主播阳台| 日韩人妻一区二区三区免费| 狠狠色噜噜狠狠狠狠色综合久| 征服好友的保守人妻| 少妇愉情理伦片高潮日本| 久久国产亚洲精品无码| FREE东北熟女HD自拍| 新妺妺窝人体色7777太粗| 免费国产成人高清在线视频| 国产极品熟女沙发内射AV| 伊人久久大香线蕉无码不卡| 少妇高潮潮喷到猛进猛出小说| 久久久久久国产精品MV|