简体   繁体   English

如何强制 object 在 Typescript 中拥有一个以联合类型命名的属性?

[英]How to force object to have a property named over a union type in Typescript?

I have the following types defined我定义了以下类型

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

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

Now, I would like to enhance MyType with something along the lines of现在,我想用类似的东西来增强MyType

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

so that I can use it like this这样我就可以像这样使用它

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

I played around it a little bit, searched the web, but I didn't come up with any solution.我玩了一下,搜索了web,但我没有想出任何解决方案。

EDIT: I just removed string from MyUnionType as requested编辑:我刚刚按要求从MyUnionType中删除了string

For this to work, you want MyType to be a union type equivalent to:为此,您希望MyType是一个联合类型,相当于:

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

This has the following desirable behavior:这具有以下理想行为:

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
}

So the only question now is how to generate MyType programmatically from MyUnionType .所以现在唯一的问题是如何从MyUnionType以编程方式生成MyType Conceptually we want to take each member K in the MyUnionType union, and produce a new union of { myProp: K } & { [P in K]: any } (which has a myProp property of type K , and a K -keyed property of type any . That is, we want to distribute the type F<K> = { myProp: K} & { [P in K]: any } operation across the MyUnionType union.从概念上讲,我们希望获取MyUnionType联合中的每个成员K ,并生成一个新联合{ myProp: K } & { [P in K]: any } (它具有类型为KmyProp属性和K键属性类型为any 。也就是说,我们要在MyUnionType联合中分发type F<K> = { myProp: K} & { [P in K]: any }操作。

This can be done a few ways, but my approach is to make what's called a distributive object type as coined in microsoft/TypeScript#47109 .这可以通过几种方式完成,但我的方法是制作所谓的分布式 object 类型,如microsoft/TypeScript#47109中所创造的。 The idea is that you make a mapped type over each K in MyUnionType , and then immediately index into it with MyUnionType , producing the desired union:这个想法是您在MyUnionType中的每个K上创建一个映射类型,然后立即使用MyUnionType 对其进行索引,从而产生所需的联合:

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

This evaluates to这评估为

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

which is equivalent to the type we want.相当于我们想要的类型。

Playground link to code Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从打字稿中的对象键字符串中提取确切的联合类型? - How to extract exact union type from object key strings in typescript? 如何在 TypeScript 中将 TypeScript 对象类型转换为像 Object.values() 这样的联合类型? - How to convert TypeScript object type to union type like Object.values() in TypeScript? Phaser 上的联合类型上不存在属性 TypeScript - Property does not exist on union type on Phaser with TypeScript Typescript 联合:类型“””上不存在属性“值” - Typescript Union: Property 'value' does not exist on type '“”' 如何强制在Typescript中的所有变量声明一个类型 - How to force all variables in Typescript to have a type declared TypeScript:为什么我不能访问仅在一个 object 上定义的联合类型的属性? - TypeScript: Why can't I access a property on a Union Type which is only defined on one object? 联合类型的部分键作为打字稿中对象的键 - Partial keys of union type as key of an object in typescript Typescript:将相似对象的并集转换为 object 类型 - Typescript: Convert union of similar objects to object type 打字稿 - 基于具有联合类型的另一个属性的条件属性给出错误 - Typescript - conditional property base on another property with Union type gives an error Typescript - 如何将部分类型分配给另一个 object 的相同类型的属性? - Typescript - How to assign Partial type to the property of same type of another object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM