我定义了以下类型

type MyUnionType = "propA" | "propB"
type MyType = {
  myProp: MyUnionType
}

type SomeOtherType = MyType & { ... /* other props*/ ... }

现在,我想用以下方法提高MyType

type MyType = {
  myProp: MyUnionType,
  [key in MyUnionType]: any // pseudo code
}

这样我就可以这样使用它了

const obj: SomeOtherType = {
  myProp: "propA",
  propA: "some value" // if this is missing, compiler will error
  [...] // some other props
}

我试了一下,搜索了一下网页,但没有找到任何解决方案.

编辑:我刚按要求从MyUnionType中删除了string

推荐答案

为了实现这一点,您希望MyType等于union type:

type MyType = {myProp: "propA", propA: any} | {myProp: "probB", propB: any}

这具有以下理想行为:

const goodObjA: MyType = {
  myProp: "propA",
  propA: "some value" 
} // okay

const badObjA: MyType = { // error! Property propA is missing
  myProp: "propA",
}

const goodObjB: MyType = {
  myProp: "propB",
  propB: "some value" 
} // okay

const badObjB: MyType = {
  myProp: "propB",
  propA: "oops" // error, unexpected property
}

因此,现在唯一的问题是如何从MyUnionType中以编程方式生成MyType.从概念上讲,我们希望在MyUnionType并集中获取每个成员K,并生成一个新的{ myProp: K } & { [P in K]: any }并集(其具有myProp类型的属性KK类型的键控属性any).也就是说,我们希望在MyUnionType并集中执行type F<K> = { myProp: K} & { [P in K]: any }操作.

有几种方法可以做到这一点,但我的方法是按照microsoft/TypeScript#47109年创造的distributive object type.这个 idea 是在MyUnionType中的K上各画一个mapped type,然后立即用MyUnionType画一个index into it,生成所需的并集:

type MyType = { [K in MyUnionType]:
  { myProp: K } & { [P in K]: any }
}[MyUnionType]

其计算结果为

type MyType = 
  ({ myProp: "propA"; } & { propA: any; }) | 
  ({ myProp: "propB"; } & { propB: any; });

这相当于我们想要的类型.

Playground link to code

Javascript相关问答推荐

有什么(最佳)方法可以从模块中获取脚本模块的多姆元素吗?

使搜索栏更改语言

如何通过使用vanilla JS限制字体大小增加或减少两次来改变字体大小

使用GraphQL查询Uniswap的ETH价格

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

未定义引用错误:未定义&Quot;而不是&Quot;ReferenceError:在初始化&Quot;之前无法访问';a';

ChartJs未呈现

如何在ASP.NET项目中使用Google Chart API JavaScript将二次轴线值格式化为百分比

使用js构造一个html<;ath&>元素并不能使其正确呈现

删除元素属性或样式属性的首选方法

当我点击一个按钮后按回车键时,如何阻止它再次被点击

为什么我不能使用其同级元素调用和更新子元素?

react 路由DOM有条件地呈现元素

固定动态、self 调整的优先级队列

我如何才能获得价值观察家&对象&S的价值?

当S点击按钮时,我如何才能改变它的样式?

无法在Adyen自定义卡安全字段创建中使用自定义占位符

如果查询为空,则MongoDB将所有文档与$in匹配

如何从Reaction-Redux中来自API调用的数据中筛选值

在openstreemap/leaflet中,当鼠标在 map 上移动时,如何在小工具提示中实时显示坐标