簡體   English   中英

在Typescript中映射類型的索引簽名

[英]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 []。

問題不在於如何定義TSizing1TSizing2 ,而是在調用Object.prototype.entriesObject.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM