【问题标题】:How can I make a Typescript interface with variable property names?如何使用变量属性名称制作 Typescript 接口?
【发布时间】:2022-01-09 07:44:28
【问题描述】:

我正在尝试编写一个类型别名或接口,其属性名称取决于用户输入。本质上我想说,'接受具有以下属性的对象,其键将由用户 here 指定。'

const userDefinedPropNames = { xVal: 'somestring', yVal: 'anotherstring', group: 'athirdstring' }

interface Data {
  somestring: number,
  anotherstring: number,
  athirdstring: string,

}

我尝试了几种方法来解决这个问题:使用映射类型,

interface PreData {
  xVal: number,
  yVal: number,
  group: string
}

const val = 'asdf' 

type Data = renameProps<PreData> //Record<`${val}`, number> 

type renameProps<Type> = {
  [Property in keyof Type as `${val}`]: Type[Property]
}

并使用记录

type Data = Record<`${val}`, number>

在这两种情况下,我都会收到相同的错误:

'val' 指的是一个值,但在这里被用作一个类型。您的意思是“typeof val”吗?ts(2749) 导出的类型别名“renameProps”已经或正在使用私有名称“val”。

奇怪的是,如果我用字符串或基本模板文字替换模板文字表达式,错误就会消失:

type Data = Record<`myval`, number>

这消除了错误,但没有达到我想要的效果。

我也尝试过只使用变量而不是模板文字,但这会导致同样的错误:

type Data = Record<val, number>

【问题讨论】:

  • 不清楚上面示例中type Data 所需的结果类型是什么
  • 如果你想从 const 中提取字面量类型,你应该使用typeof。例如Record&lt;typeof val, number&gt;
  • @Faero 要清楚,“用户输入”是指您的软件的用户,他们将这些字符串输入到文本字段中(在编译时不知道)?或者你的意思是这个库的消费者,一些开发人员可能会用他们自己的字符串提供这个代码(在编译时知道,但在更大的代码库的上下文中)?
  • @AlexWayne 我说的用户是使用我的库的开发人员。我正在使用 D3 制作一个反应图表组件库。我的希望是允许开发人员实例化图表,将数据与各种属性一起传递。这些属性之一将指定输入数据的哪些键用作 x 值、y 值和分组。

标签: typescript mapped-types


【解决方案1】:

这是你想要的吗?

type Data<T extends Record<string, any>> = T;

【讨论】:

  • 不确定我是否理解这一点,你能解释一下这里发生了什么吗?谢谢。
  • 这是一个接受一个类型参数(一个记录)的类型,其中键是字符串,值是任何类型。这意味着如果用户有一个对象:ts const obj: MyObj = { something: 'somestring', else: false } type NewType = Data&lt;MyObj&gt; // will be the key/value pairs of obj
猜你喜欢
  • 2019-02-13
  • 2020-12-03
  • 1970-01-01
  • 2019-12-05
  • 2018-09-22
  • 2020-02-28
  • 2018-07-14
  • 2020-10-30
  • 2011-06-09
相关资源
最近更新 更多