打字稿模板文字作为界面键 [英] typescript template literal as interface key

查看:20
本文介绍了打字稿模板文字作为界面键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想在打字稿中创建一个包含多个项目的对象,如下所示:

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'
};

Playground 代码链接

`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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆