欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TypeScript 中如何限制對(duì)象鍵名的取值范圍

 更新時(shí)間:2021年05月20日 08:50:39   作者:劉哇勇  
TypeScript由微軟開(kāi)發(fā)的自由和開(kāi)源的編程語(yǔ)言,是一種給 JavaScript 添加特性的語(yǔ)言擴(kuò)展,接下來(lái)通過(guò)本文給大家介紹TypeScript 中如何限制對(duì)象鍵名的取值范圍,感興趣的朋友跟隨小編一起看看吧

當(dāng)我們使用 TypeScript 時(shí),我們想利用它提供的類(lèi)型系統(tǒng)限制代碼的方方面面,對(duì)象的鍵值,也不例外。

譬如我們有個(gè)對(duì)象存儲(chǔ)每個(gè)年級(jí)的人名,類(lèi)型大概長(zhǎng)這樣:

type Students = Record<string, string[]>;

理所當(dāng)然地,數(shù)據(jù)就是長(zhǎng)這樣:

const students: Students = {
  Freshman: ["David", "John"],
  sophomore: [],
  Junior: ["Lily"],
  Senior: ["Tom"],
};

限制對(duì)象鍵名為枚舉

上面數(shù)據(jù)類(lèi)型的問(wèn)題是,年級(jí)是有限的幾種可值取,而該對(duì)象上可任意添加屬性,這樣顯得數(shù)據(jù)不夠純粹。

所以我們新增枚舉,列出可取的值:

export enum Grade {
  Freshman,
  sophomore,
  Junior,
  Senior,
}

現(xiàn)在,把對(duì)象的鍵名限制為上面枚舉就行了。

- type Students = Record<string, string[]>;
+ type Students = Record<Grade, string[]>;

這樣我們的數(shù)據(jù)可寫(xiě)成這樣:

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"],
};

這樣,限制住了對(duì)象身上鍵名的范圍,可以看到如果添加一個(gè)枚舉之外的鍵會(huì)報(bào)錯(cuò)。

更加語(yǔ)義化的枚舉值

但上面的做法還是有不妥之處,因?yàn)槊杜e值默認(rèn)是從 0 開(kāi)始的數(shù)字,這樣,作為鍵值就不夠語(yǔ)義了,這點(diǎn)從訪(fǎng)問(wèn)對(duì)象的屬性時(shí)體現(xiàn)了出來(lái):

修正我們的枚舉,用更加語(yǔ)義的文本作為其值:

export enum Grade {
  Freshman = "Freshman",
  sophomore = "sophomore",
  Junior = "Junior",
  Senior = "Senior",
}

此時(shí)再使用該枚舉時(shí),得到的就不是無(wú)意義的數(shù)字了。

如果你愿意,枚舉值也可以是中文,

export enum Grade {
  Freshman = "大一萌新",
  sophomore = "大二學(xué)弟",
  Junior = "大三學(xué)妹",
  Senior = "大四老司機(jī)",
}

使用時(shí)也是沒(méi)任何問(wèn)題的:

鍵值可選

上面的類(lèi)型定義還有個(gè)問(wèn)題,即,它要求使用時(shí)對(duì)象包含枚舉中所有值,比如 sophomore 這個(gè)年級(jí)中并沒(méi)有人,可以不寫(xiě),但會(huì)報(bào)錯(cuò)。

// ❌ 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)化類(lèi)型為可選:

type Students = Partial<Record<Grade, string[]>>;

假若可選的值不是通過(guò)枚舉定義,而是來(lái)自一個(gè)數(shù)組,

const grades = ["Freshman", "sophomore", "Junior", "Senior"];

這意味著我們需要提取數(shù)組中的值形成一個(gè)聯(lián)合類(lèi)型。

首先利用const assertions 把數(shù)組轉(zhuǎn)元組(Tuple)類(lèi)型,

const grades = <const>["Freshman", "sophomore", "Junior", "Senior"];

再利用 typeofLookup Types 得到最終的聯(lián)合類(lèi)型:

// 實(shí)際為 type Keys = "Freshman" | "sophomore" | "Junior" | "Senior"
type Keys = typeof grades[number];

最后數(shù)據(jù)類(lèi)型和數(shù)據(jù)可寫(xiě)成:

type Students = Partial<Record<Keys, string[]>>;

const students: Students = {
  Freshman: ["David", "John"],
  Junior: ["Lily"],
  Senior: ["Tom"],
};

須知這種形式下,對(duì)象的 key 與原數(shù)組中元素其實(shí)沒(méi)有語(yǔ)法層面的關(guān)聯(lián),即,編輯器的「跳轉(zhuǎn)定義」是不可用的。

盡量還是保持代碼之間的關(guān)聯(lián)才能體現(xiàn)出 TypeScript 的作用,所以像這種只有類(lèi)型約束而無(wú)法建立關(guān)聯(lián)的操作是不建議的。

相關(guān)資源

const assertions

keyof and Lookup Types

The text was updated successfully, but these errors were encountered:

以上就是TypeScript 中限制對(duì)象鍵名的取值范圍的詳細(xì)內(nèi)容,更多關(guān)于TypeScript限制對(duì)象鍵名范圍的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論