TypeScript 中如何限制對象鍵名的取值范圍
當我們使用 TypeScript 時,我們想利用它提供的類型系統(tǒng)限制代碼的方方面面,對象的鍵值,也不例外。
譬如我們有個對象存儲每個年級的人名,類型大概長這樣:
type Students = Record<string, string[]>;
理所當然地,數(shù)據(jù)就是長這樣:
const students: Students = { Freshman: ["David", "John"], sophomore: [], Junior: ["Lily"], Senior: ["Tom"], };
限制對象鍵名為枚舉
上面數(shù)據(jù)類型的問題是,年級是有限的幾種可值取,而該對象上可任意添加屬性,這樣顯得數(shù)據(jù)不夠純粹。
所以我們新增枚舉,列出可取的值:
export enum Grade { Freshman, sophomore, Junior, Senior, }
現(xiàn)在,把對象的鍵名限制為上面枚舉就行了。
- type Students = Record<string, string[]>; + type Students = Record<Grade, string[]>;
這樣我們的數(shù)據(jù)可寫成這樣:
const students: Students = { [Grade.Freshman]: ["David", "John"], [Grade.sophomore]: [], [Grade.Junior]: ["Lily"], [Grade.Senior]: ["Tom"], // ❌ Object literal may only specify known properties, and 'blah' does not exist in type 'Students'.ts(2322) blah: ["some one"], };
這樣,限制住了對象身上鍵名的范圍,可以看到如果添加一個枚舉之外的鍵會報錯。
更加語義化的枚舉值
但上面的做法還是有不妥之處,因為枚舉值默認是從 0 開始的數(shù)字,這樣,作為鍵值就不夠語義了,這點從訪問對象的屬性時體現(xiàn)了出來:
修正我們的枚舉,用更加語義的文本作為其值:
export enum Grade { Freshman = "Freshman", sophomore = "sophomore", Junior = "Junior", Senior = "Senior", }
此時再使用該枚舉時,得到的就不是無意義的數(shù)字了。
如果你愿意,枚舉值也可以是中文,
export enum Grade { Freshman = "大一萌新", sophomore = "大二學弟", Junior = "大三學妹", Senior = "大四老司機", }
使用時也是沒任何問題的:
鍵值可選
上面的類型定義還有個問題,即,它要求使用時對象包含枚舉中所有值,比如 sophomore
這個年級中并沒有人,可以不寫,但會報錯。
// ❌ Property 'sophomore' is missing in type '{ Freshman: string[]; Junior: string[]; Senior: string[]; }' but required in type 'Students'.ts(2741) const students: Students = { [Grade.Freshman]: ["David", "John"], // [Grade.sophomore]: [], [Grade.Junior]: ["Lily"], [Grade.Senior]: ["Tom"], };
所以,優(yōu)化類型為可選:
type Students = Partial<Record<Grade, string[]>>;
假若可選的值不是通過枚舉定義,而是來自一個數(shù)組,
const grades = ["Freshman", "sophomore", "Junior", "Senior"];
這意味著我們需要提取數(shù)組中的值形成一個聯(lián)合類型。
首先利用const assertions 把數(shù)組轉元組(Tuple)類型,
const grades = <const>["Freshman", "sophomore", "Junior", "Senior"];
再利用 typeof
和 Lookup Types 得到最終的聯(lián)合類型:
// 實際為 type Keys = "Freshman" | "sophomore" | "Junior" | "Senior" type Keys = typeof grades[number];
最后數(shù)據(jù)類型和數(shù)據(jù)可寫成:
type Students = Partial<Record<Keys, string[]>>; const students: Students = { Freshman: ["David", "John"], Junior: ["Lily"], Senior: ["Tom"], };
須知這種形式下,對象的 key 與原數(shù)組中元素其實沒有語法層面的關聯(lián),即,編輯器的「跳轉定義」是不可用的。
盡量還是保持代碼之間的關聯(lián)才能體現(xiàn)出 TypeScript 的作用,所以像這種只有類型約束而無法建立關聯(lián)的操作是不建議的。
相關資源
The text was updated successfully, but these errors were encountered:
以上就是TypeScript 中限制對象鍵名的取值范圍的詳細內容,更多關于TypeScript限制對象鍵名范圍的資料請關注腳本之家其它相關文章!
相關文章
Add a Picture to a Microsoft Word Document
Add a Picture to a Microsoft Word Document...2007-06-06Nodejs使用mysql模塊之獲得更新和刪除影響的行數(shù)的方法
業(yè)余時間玩nodejs的時候遇到的情況, 在使用mysql模塊連接mysql操作, 想在update, delete語句的時候, 想知道到底update, delete成功了沒有2014-03-03javascript實現(xiàn)獲取圖片大小及圖片等比縮放的方法
這篇文章主要介紹了javascript實現(xiàn)獲取圖片大小及圖片等比縮放的方法,涉及javascript針對圖形圖像相關屬性獲取與修改相關操作技巧,需要的朋友可以參考下2016-11-11javascript字符串拆分成單個字符相加和不超過10,求最終值
javascript字符串拆分成單個字符相加和不超過10,求最終值2008-09-09