TypeScript:在对象上实施单个动态键

时间:2019-02-08 06:43:10

标签: typescript typescript-typings

是否可以为具有单个动态命名键的对象编写接口?

我能够编写一个接受任意数量的动态命名键的接口,但我想将其限制为仅一个。

让我们从一些基础知识开始,逐步解决我的问题。在以下界面中,该对象只能有一个键,并将其命名为“ id”:

interface Test {
  id: string
}

这很好,因为具有此接口的对象只能具有一个属性id。但是我需要使用者能够指定此键的名称。

如果我将该界面更改为以下界面,则它允许使用者指定自定义键:

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

这使我更接近要查找的内容,如本例所示:

type SpecificTest = Test<"customId">;

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

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

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

我在想遵循这些思路的某些方法可以解决问题(使用伪代码):

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

但是该特定语法无效。

有什么方法可以定义一个用户只能定义一个单个动态命名键的接口?

1 个答案:

答案 0 :(得分:3)

您可以通过IsUnion帮助程序类型

来检测传递的类型是否为联合。
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}