淺談TypeScript 索引簽名的理解
目錄
- 1.什麼是索引簽名
- 2. 索引簽名語法
- 3. 索引簽名的注意事項
- 3.1不存在的屬性
- 3.2 string 和 number 鍵
- 4.索引簽名與 Record<Keys,Type>對比
我們用兩個物件來描述兩個碼農的工資:
const salary1 = { baseSalary: 100_000,yearlyBonus: 20_000 }; const salary2 = { contractSalary: 110_000 };
然後寫一個獲取總工資的函式
function totalSalary(salaryObject: ???) { let total = 0; for (const name in salaryObject) { total += salaryObject[name]; } return total; } totalSalary(salary1); // => 120_000 totalSalary(salary2); // => 110_000
如果是你的,要如何宣告totalSalary()
函式的salaryObject
引數,以接受具有字串鍵和數字值的物件?
答案是使用一個索引簽名!
接著,我們來看看什麼是 TypeScript
索引簽名以及何時需要它們。
1.什麼是索引簽名
索引簽名的思想是在只知道鍵和值型別的情況下對結構未知的物件進行型別劃分。
它完全符合salary
引數的情況,因為函式應該接受不同結構的salary
物件,唯一的要求是屬性值為數字。
我們用索引簽名來宣告salaryObject
引數
function totalSalary(salaryObject: { [key: string]: number }) { let total = 0; for (const name in salaryObject) { total += salaryObject[name]; } return total; } totalSalary(salary1); // => 120_000 totalSalary(salary2); // => 110_000
{[key: string]: number}
是索引簽名,它告訴TypeScript salaryObject
必須是一個以string
型別為鍵,以 number
型別為值的物件。
2. 索引簽名語法
索引簽名的語法相當簡單,看起來與屬性的語法相似,但有一點不同。我們只需在方括號內寫上鍵的型別,而不是屬性名稱:{ [key: KeyType]: ValueType
}。
下面是一些索引簽名的例子。
string
型別是鍵和值。
interface StringByString { [key: string]: string; } const heroesInBooks: StringByString = { 'Gunslinger': '前端小智','Jack Torrance': '王大志' };
string
型別是鍵,值可以是 string
、number
或boolean
interface Options { [key: string]: string | number | boolean; timeout: number; } const options: Options = { timeout: 1000,timeoutMessage: 'The request timed out!',isFileUpload: false };
簽名的鍵只能是一個 string
`、number
或 symbol
`。其他型別是不允許的。
3. 索引簽名的注意事項
TypeScript
中的索引簽名有一些注意事項,需要注意。
3.1不存在的屬性
如果試圖訪問一個索引簽名為 { [key: strin客棧g]: string
} 的物件的一個不存在的屬性,會發生什麼?
正如預期的那樣,TypeScript
將值的型別推斷為 string
。但是檢查執行時值,它是undefined
:
根據 TypeScript
提示,value
變數是一個 string
型別,但是它的執行時值是 undefined
。
索引簽名只是將一個鍵型別對映到一個值型別,僅此而已。如果沒有使這種對映正確,值型別可能會偏離實際的執行時資料型別。
為了使輸入更準確,將索引值標記為 string
或 undefined
。這樣,TypeScript
就會意識到你訪問的屬性可能不存在
3.2 string 和 number 鍵
假設有一個數字名稱的字典:
interface NumbersNames { [key: string]: string程式設計客棧 } const names: NumbersNames = { '1': 'oOEhXFJBULsne','2': 'two','3': 'three',// ... };
不會,正常工作。
當在屬性訪問器中作為鍵使用時,隱式地將數字強制為字串(
names[1]
與names['1'
]相同)。TypeScript
也會執行這個強制。
你可以認為 [key: string
] 與 [key: string | number]
相同。
4.索引簽名與 Record<Keys,Type>對比
TypeScript
有一個實用型別 Record<Keys,Type>,
類似於索引簽名。
conOEhXFJBULsst object1: Record<string,string> = { prop: 'Value' }; // OK const object2: { [key: string]: string } = { prop: 'Value' }; // OK
那問題來了...什麼時候使用 Record<Keys,Type>,
什麼時候使用索引簽名?乍一看,它們看起來很相似
我們知道,索引簽名只接受 string
、number
或 symbol
作為鍵型別。如果你試圖在索引簽名中使用,例如,字串字面型別的聯合作為鍵,這是一個錯誤。
索引簽名在鍵方面是通用的。
但是我們可以使用字串字面值的聯合來描述 Record<keys,Type>
中的鍵
type Salary = Record<'yearlySalary'|'yearlyBonus',number> const salary1: Salary = { 'yearlySalary': 120_000,'yearlyBonus': 10_000 }; // OK
Record<Keys,Type>
是為了具體到鍵的問題。
建議使用索引簽名來註釋通用物件,例如,鍵是字串型別。但是,當你事先知道鍵的時候,使用Record<Keys,Type>
來註釋特定的物件,例如字串字面量' prop1' | 'prop2'
被用於鍵值。
總結:
如果你不知道你要處理的物件結構,但你知道可能的鍵和值型別,那麼索引簽名就是你需要的。
索引簽名由方括號中的索引名稱及其型別組成,後面是冒號和值型別: { [indexName: KeyType]: ValueType }, KeyType
可以是一個 string
、number
或 symbol
,而ValueType
可以是任何型別。
到此這篇關於淺談TypeScript 索引簽名的理解的文章就介紹到這了,更多相關TypeScript 索引簽名內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!