TypeScript:在对象上强制执行单个动态键 [英] TypeScript: enforcing a single dynamic key on an object

查看:35
本文介绍了TypeScript:在对象上强制执行单个动态键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法为具有单个动态命名键的对象编写接口?

Is there a way to write an interface for an object that has a single dynamically-named key?

我可以编写一个接口来接受任意数量的动态命名的键,但我想将其限制为一个.

I'm able to write an interface that accepts any number of dynamically-named keys, but I'd like to restrict it to just one.

让我们从一些基础知识开始,然后逐步解决我的问题.在下面的界面中,对象只能有一个键,命名为id":

Let's start with some basics, and work our way up to my problem. In the following interface, the object can only have a single key, and it is named "id":

interface Test {
  id: string
}

这很好,因为这个接口的对象只能有一个属性,id.但我需要消费者能够指定这个键的名称.

This is good in that objects with this interface can only have one property, id. But I need the consumer to be able to specify the name of this key.

如果我将该接口更改为以下内容,则它允许消费者指定自定义键:

If I change that interface to be the following, it allows a consumer to specify a custom key:

type Test<K extends string> = {
  [P in K]: string
}

这让我更接近我正在寻找的东西,正如我们在这个例子中看到的:

This gets me closer to what I am looking for, as we can see in this example:

type SpecificTest = Test<"customId">;

const test:SpecificTest = {
  customId: 'pls',
}

但是,用户可以传递联合类型来定义多个 ID 字段,这就是问题所在.

However, the user can pass a union type to define multiple ID fields, and that's where things go awry.

// I don't want a user to be able to pass multiple strings here
type SpecificTest = Test<"customId"|"anotherId">;

const test:SpecificTest = {
  customId: 'pls',

  // :(
  anotherId: 'blah'
}

我在想这些东西可能会奏效(在伪代码中):

I was thinking something along these lines might do the trick (in pseudocode):

type Test<K extends string> = {
  [K]: string
}

但是那个特定的语法不起作用.

but that specific syntax doesn't work.

有没有办法定义一个接口,用户只能定义一个单个动态命名的键?

Is there any way to define an interface where a user can only define a single dynamically-named key?

推荐答案

您可以通过 IsUnion 辅助类型

You can detect if the passed type is a union by IsUnion helper type

type Test<K extends string> = IsUnion<K> extends true ? Error<'Please don\'t pass a union'>  : {
  [P in K]: string
}

interface Error<M> {msg: M}

这篇关于TypeScript:在对象上强制执行单个动态键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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