打字稿模板文字作为界面键 [英] typescript template literal as interface key
问题描述
假设我想在打字稿中创建一个包含多个项目的对象,如下所示:
Lets say that I want to create a object contain multiple items in typescript as below:
const obj: Items = {
item1: 'foo',
item2: 'bar',
item3: 'baz',
}
我应该如何声明我的 Items 类型以使其与任意数量的项目兼容?我使用 Typescript 4.1 中的模板文字尝试了以下操作,但似乎不起作用:
How should I declare my Items type so that it's compatible with any number of items? I tried the following with template literals from Typescript 4.1 and it doesn't seem to work:
interface Items {
[P: `array${number}`]: any;
}
是否可以声明这样的类型?
Is it possible to declare a type like this?
推荐答案
UPDATE FOR TS4.4+
TypeScript 4.4 将支持包含模式模板文字的索引签名,如在 microsoft/TypeScript#44512 中实现的那样.然后,您将能够将 Items
声明为特定类型,如下所示:
UPDATE FOR TS4.4+
TypeScript 4.4 will support index signatures that include pattern template literals, as implemented in microsoft/TypeScript#44512. You will then be able to declare Items
as a specific type, like this:
interface Items {
[key: `item${number}`]: any;
}
您可以验证它是否按预期工作:
And you can verify that it works as desired:
const obj: Items = {
item1: 'foo',
item2: 'bar',
item2021: 'baz',
item3: 'qux',
};
const objBad: Items = {
item1: 'foo',
item2: 'bar',
itemMMXXI: 'baz', // error!
// ~~~~~~~~~ <--
// Object literal may only specify known properties,
// and 'itemMMXXI' does not exist in type 'Items'
item3: 'qux'
};
`item${number}`
形式的模式模板文字(在 microsoft/TypeScript#40598)目前不允许作为键类型.
Pattern template literals of the form `item${number}`
(as implemented in microsoft/TypeScript#40598) are not currently allowed as key types, as of TypeScript 4.1.
目前没有与您想要的 Items
类型相对应的特定类型.相反,您可以将其表示为类型上的 约束 并编写一个辅助函数 asItems()
,它只接受符合约束的输入:
For now there is no specific type corresponding to your desired Items
type. Instead, you could represent it as a constraint on a type and write a helper function asItems()
which will only accept inputs that adhere to the constraint:
const asItems = <K extends PropertyKey>(
obj: { [P in K]: P extends `item${number}` ? any : never }
) => obj;
将检查传入的obj
的每个键是否可分配给`item${number}`
.如果是,则属性类型为any
,否则,属性类型为never
.这往往会导致任何违规属性出现错误:
Each key of the passed-in obj
will be checked for whether it is assignable to `item${number}`
. If so, the property type is any
, and if not, the property type is never
. That will tend to cause errors on any offending property:
const obj = asItems({
item1: 'foo',
item2: 'bar',
item2021: 'baz',
item3: 'qux',
}); // okay
const objBad = asItems({
item1: 'foo',
item2: 'bar',
itemMMXXI: 'baz', // error!
// ~~~~~~~~~ <-- Type 'string' is not assignable to type 'never'
item3: 'qux'
});
这篇关于打字稿模板文字作为界面键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!