首页 > 解决方案 > 如何在仍然在 TS 中指定值类型的同时保留隐式键名键入作为接口的一部分?

问题描述

我真的很想能够定义一个对象的接口/类型,它允许我定义值是什么,但是在类型中使用对象的键作为可能的键集。可视化,我想找到一个替代方案:

interface IElementType = {[key: string]: SpecialProperties}

并用类似的东西替换

interface IElementType = {[key: keyof elements]: SpecialProperties}

在一个例子中

const elements: IElementType = {
  pirate: {
    name: 'patchy',
    type: 'matey'
  },
  captain: {
    name: 'peggy',
    type: 'pegleg'
  },
  ...
}


// for reference
interface SpecialProperties {
  name: string,
  type: string
}

我在哪里keyof elements弥补我希望的可能(知道这不能工作,因为elements它是一个 js 对象)但我希望我只是在错误地思考它。这里的动机是在将此变量导入项目的另一部分时保留类型信息/智能感知。然后我可以输入elements.pirate,ts 就会知道这个键存在。当我们使用时,[key: string]我们实际上是在匿名化对象中的键并将这些信息丢弃。与我们在没有任何显式类型的情况下定义变量时相反

const elements = { ... }

其中 ts 使用包含对象包含的显式键的类型隐式键入此变量,因此在上述情况下,该类型将与完整对象的值完全匹配。

我希望这里有一些中间立场,我们可以保留键名的隐式类型,但强制它们的值是特定的。这可能吗?

标签: typescript

解决方案


对于这个例子...

const elements: IElementType = {
  pirate: {
    name: 'patchy',
    type: 'matey'
  },
  captain: {
    name: 'peggy',
    type: 'pegleg'
  },
  ...
}

...要工作,定义IElementType为通用接口,但interface在这种情况下使用声明不起作用。:(

type IElementType<K extends string> = ​{
  ​[x in K]: SpecialProperties;
};

elements变量将是IElementType<'pirate' | 'captain'>前两个键的类型。


推荐阅读