TypeScript 中如何限制對象鍵名的取值范圍
當(dāng)我們使用 TypeScript 時,我們想利用它提供的類型系統(tǒng)限制代碼的方方面面,對象的鍵值,也不例外。
譬如我們有個對象存儲每個年級的人名,類型大概長這樣:
type Students = Record<string, string[]>;
理所當(dāng)然地,數(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"],
};
這樣,限制住了對象身上鍵名的范圍,可以看到如果添加一個枚舉之外的鍵會報錯。
更加語義化的枚舉值
但上面的做法還是有不妥之處,因為枚舉值默認(rèn)是從 0 開始的數(shù)字,這樣,作為鍵值就不夠語義了,這點從訪問對象的屬性時體現(xiàn)了出來:
修正我們的枚舉,用更加語義的文本作為其值:
export enum Grade {
Freshman = "Freshman",
sophomore = "sophomore",
Junior = "Junior",
Senior = "Senior",
}
此時再使用該枚舉時,得到的就不是無意義的數(shù)字了。
如果你愿意,枚舉值也可以是中文,
export enum Grade {
Freshman = "大一萌新",
sophomore = "大二學(xué)弟",
Junior = "大三學(xué)妹",
Senior = "大四老司機(jī)",
}
使用時也是沒任何問題的:
鍵值可選
上面的類型定義還有個問題,即,它要求使用時對象包含枚舉中所有值,比如 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ù)組轉(zhuǎn)元組(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ù)組中元素其實沒有語法層面的關(guān)聯(lián),即,編輯器的「跳轉(zhuǎn)定義」是不可用的。
盡量還是保持代碼之間的關(guān)聯(lián)才能體現(xiàn)出 TypeScript 的作用,所以像這種只有類型約束而無法建立關(guān)聯(lián)的操作是不建議的。
相關(guān)資源
The text was updated successfully, but these errors were encountered:
以上就是TypeScript 中限制對象鍵名的取值范圍的詳細(xì)內(nèi)容,更多關(guān)于TypeScript限制對象鍵名范圍的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS按鈕倒計時并跳轉(zhuǎn)到新地址的實現(xiàn)代碼
在完成某項操作時,按鈕上有個倒計時效果,倒計時結(jié)束后,跳轉(zhuǎn)到新地址,這篇文章主要介紹了JS按鈕倒計時并跳轉(zhuǎn)到新地址,需要的朋友可以參考下2023-02-02
javascript firefox不顯示本地預(yù)覽圖片問題的解決方法
在Firefox一直不能用js做出圖片預(yù)覽的效果,下面這個即可解決,用替換的方法實現(xiàn)firefox支持得的路徑格式2008-11-11
js屏蔽F12審查元素,禁止修改頁面代碼等實現(xiàn)代碼
有時候我們需要屏蔽客戶端的F12,以防菜鳥也可以隨意修改我們的代碼,也處于源碼的保護(hù)等操作,這里就為大家分享一下常見的代碼2020-10-10
js實現(xiàn)隨機(jī)點名系統(tǒng)(實例講解)
下面小編就為大家?guī)硪黄猨s實現(xiàn)隨機(jī)點名系統(tǒng)(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10





