TypeScript 型別挑戰:元組轉換為物件
高質量的型別可以提高專案的可維護性並避免一些潛在的漏洞。
一些前端面試中考察到了 TypeScript 高階型別的定義,本系列主要解答來自 Type Challenges 專案中的 TS 型別挑戰問題,以此更好的瞭解 TS 的型別系統,編寫自己的型別工具,更好的應對前端面試。
下面來看一個難度為簡單的題目:元組轉換為物件
題目描述
傳入一個元組型別,將這個元組型別轉換為物件型別,這個物件型別的鍵/值都是從元組中遍歷出來。
例如:
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const type result = TupleToObject<typeof tuple> // expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
題目解答
我們需要從陣列中獲取所有值,並將其作為新物件中的鍵和值。
首先我們知道什麼是元組,來看TypeScript 對元組的定義:
元組型別是另一種Array型別,它確切地知道包含多少個元素,以及它在特定位置包含哪些型別。
這意味著我們可以檢查length並得到確切的數字:
const fullName:[first: string, last: string] = ['hello', 'world']; const range:[start: number, end: number] = [0, 10]; const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] as const; type FullNameLength = (typeof fullName)['length'] // 2 type RangeLength = (typeof range)['length'] // 2 type DigitsLength = (typeof digits)['length'] // 10
而在陣列中就無法實現這一點:
const fullName:string[] = ['hello', 'world']; const range:number[] = [0, 10]; type FullNameLength = (typeof fullName)['length'] // number type RangeLength = (typeof range)['length'] // number
可以使用對映型別來遍歷物件:
type MappedType<T> = { [Key in keyof T]: T[Key]; };
- keyof T用於從物件型別T中獲取鍵值 key;
- in用於對物件鍵值key進行迭代;
- Key 就是物件鍵值 key 本身;
- T[Key]是指定 Key 的值;
我們使用索引訪問型別來遍歷元組,可以通過T[number]從元組中獲取值。具體實現如下:
type TupleToObject<T> = { [Value in T[number]]: Value; };
- T[number] 用於從元組 T 中獲取值;
- in 用於迭代元組值;
- Value 是元組元素,用作構建物件的key和value。
但是這時候報錯了:
這時就需要約束泛型的型別,最終的實現如下:
type TupleToObject<T extends readonly any[]> = { [Value in T[number]]: Value; };
這裡的extends readonly any[] 是呼叫T[number] 所必須的,用來約束 T 的型別,T是一個元組,元組元素是隻讀的。
Type Challenges:https://github.com/type-challenges/type-challenges
「其他文章」
- 一篇學會樹的子結構
- 從20s優化到500ms,我用了這三招
- 使用 rustup 管理你的 Rust 工具鏈
- Java反序列化基礎篇-JDK動態代理
- iOS 16 即將讓你的 iPhone 擺脫那些特別讓人煩的驗證碼和垃圾廣告
- 刷演算法題常用的 JS 基礎掃盲
- 跨區域、Kubernetes叢集執行資料庫實踐指南
- 13個你應該知道的 Webpack 優化技巧
- Python進行資料視覺化,你會用什麼庫來做呢?
- Python常見報錯及解決方案,建議收藏!
- 介紹一款進階版的 Pandas 資料分析神器:Polars
- Python包管理工具之Pipenv
- 「Spring」Boot Docker 認證指南(上)
- 基於Electron開發Hosts切換工具的“踩坑”之旅
- 2022 年需求中優秀的 DevOps 工具
- 一日一技:如何實現帶Timeout的Input?
- 13 個非常有用的 Python 程式碼片段,建議收藏!
- [科普文] 淺談 Function Programing 程式設計正規化
- 什麼是Pulsar函式流處理應用?
- Flask vs Django: 該如何選擇Python框架?