【问题标题】:Nested object type definition嵌套对象类型定义
【发布时间】:2020-04-21 15:24:49
【问题描述】:

我有一个嵌套对象,我想为它写一个类型定义。这是对象:

const colors = {
  grayscale: {
    black: '#141414',
    darkGray: '#303030',
    white: '#F0F0F0',
  },
  green1: '#1DB954',
  green2: '#1ED760',
}

这是我尝试编写类型定义的方式:

interface ObjectOf<V> {
  [_: string]: V
}

type ColorObject = ObjectOf<string> | string
type Colors = ObjectOf<ColorObject>

const colors: Colors = {
  ... (same object as above)
}

我使用ObjectOf&lt;V&gt; 来创建一个对象,该对象可以具有任何字符串键,但只能具有V 类型的值。这似乎适用于未嵌套的对象。

当我尝试像这样使用这个对象时:colors.grayscale.black,打字稿编译器给了我这个错误:

Property 'black' does not exist on type 'ColorObject'.
  Property 'black' does not exist on type 'string'.  TS2339

  > 82 |     backgroundColor: colors.grayscale.black,
       |                                       ^

似乎打字稿忽略了ColorObject 可以是ObjectOf&lt;&gt; 的事实,这意味着任何字符串都应该是有效的键。相反,它认为它只能是一个字符串,因此获取grayscale 对象的black 键失败。为什么会这样,和/或如何修复类型定义以便可以按原样使用颜色对象?

【问题讨论】:

  • 不能忽略它可以ObjectOf&lt;string&gt;。它担心它可能string,在这种情况下它不会有一个名为black 的属性。您只能访问存在于联合的所有成员中的联合的属性。或者你必须通过测试消除工会成员,例如if (typeof colors.grayscale === "string") throw new Error();,然后访问colors.grayscale.black。为什么将colors 注释为Colors?这是一个相当广泛的类型,故意忘记了colors 的结构。你的用例是什么?
  • 我明白了,这是有道理的。我的用例是在 React 组件中使用颜色对象和另一个类似的对象作为样式。当我对只能接受某些字符串(如 flexDirection)的属性使用“row”之类的字符串时,Typescript 给了我错误,即使“row”是这些有效值之一。我想我会指定所有这些对象的类型以避免这种情况,但我想这不是最好的解决方案。
  • 我摆脱了颜色的类型定义,我可能会就我遇到的实际问题发布一个不同的问题(现在我正在使用类型转换来安抚编译器,但如果那是最佳解决方案)。感谢您的指导!
  • 下面的呢:ts const colors = { grayscale: { black: '#141414', darkGray: '#303030', white: '#F0F0F0', }, green1: '#1DB954', green2: '#1ED760', } as const type Colors = typeof colors 我倾向于在有一些具体结构的地方使用它,并且我想从中建立一个强大的合同。我只能导出应用程序的类型和事实来源将是colors 对象。当您在其中添加删除内容时,类型会自动更新。缺点很少,但我相信仍然有用。
  • @rusev 谢谢,这正是我所需要的!您想将此作为答案提交以便我接受吗?如果没有,我会将其作为我自己的答案发布,以便其他人可以看到。

标签: typescript


【解决方案1】:

下面的呢:

const colors = { 
  grayscale: { 
    black: '#141414', 
    darkGray: '#303030', 
    white: '#F0F0F0', 
  }, 
  green1: '#1DB954', 
  green2: '#1ED760', 
} as const 

type Colors = typeof colors 

我倾向于在我有一些具体结构的地方使用它,并且我想从中建立一个强有力的合同。我只能导出应用程序的类型和事实来源将是颜色对象。当您在其中添加删除内容时,类型会自动更新。缺点很少,但我相信仍然有用。

【讨论】:

  • 我很确定我不需要 type Colors = typeof colors,因为我导出 colors 并且 typescript 在整个项目中都知道它的类型
猜你喜欢
  • 2020-09-30
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
相关资源
最近更新 更多