[英]Index signature for a mapped type in Typescript
type Scales = 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'
type TScale = { [k in Scales]: number }
type TSizing1 = { [k in Scales]?: string }
type TSizing2 = { [k in Scales]: string }
const scale: TScale = {
xxs: 1 / 8,
xs: 1 / 4,
s: 1 / 2,
m: 1,
l: 2,
xl: 4,
xxl: 8,
}
const sizing1: TSizing1 = {}
Object.entries(scale).forEach(([key, value]: [string, number]) => {
sizing1[key] = `${value * 1.6}rem`
})
const sizing2: TSizing2 = Object.assign(
{},
...Object.keys(scale).map(k => ({ [k]: `${scale[k] * 1.6}rem` })),
)
sizing1和sizing2都會出錯,因為TSizing1和TScale上分別缺少索引簽名。 但是我應該如何為映射類型添加索引簽名呢?
錯誤是有意義的,因為您不能將string
鍵分配給具有特定鍵和沒有索引簽名的接口(索引簽名是指示接口應該為未知鍵返回的指令,即string
鍵)。
因此,您應該像這樣更改您的代碼:
Object.entries(scale).forEach(([key, value]: [Scales /* EDIT1 */, number]) => {
sizing1[key] = `${value * 1.6}rem`
})
const sizing2: TSizing2 = Object.assign(
{},
...Object.keys(scale).map((k) => ({ [k]: `${scale[k as Scales] /*EDIT2*/ * 1.6}rem` })),
)
我希望第一次編輯(EDIT1)很清楚。 第二個(EDIT2)是一個必要的惡,因為即使參數已知類型, Object.keys
仍然只返回string []。
問題不在於如何定義TSizing1
或TSizing2
,而是在調用Object.prototype.entries
或Object.prototype.keys
時如何處理對象類型。
解
在對象上操作時,告訴TypeScript使用縮小的特定類型。 替換這些:
Object.entries(scale)
Object.keys(scale)
和那些:
(Object.entries(scale) as [Scales, number][])
(Object.keys(scale) as Scales[])
所以解決方案看起來像:
(Object.entries(scale) as [Scales, number][]).forEach(([key, value]) => {
sizing1[key] = `${value * 1.6}rem`;
});
const sizing2: TSizing2 = Object.assign(
{},
...(Object.keys(scale) as Scales[]).map(k => ({ [k]: `${scale[k] * 1.6}rem` })),
);
說明
在推斷對象類型時,TypeScript非常糟糕。 即使我們確切地知道scale
哪些鍵(它們是非常明確定義的Scales
),TypeScript也會將它們視為類似string
一些數據。 信息丟失了。
為了彌補這種損失,斷言他們的類型是你所知道的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.