首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型记录:将标记的联合转换为联合类型

问类型记录:将标记的联合转换为联合类型
EN

Stack Overflow用户
提问于 2020-06-26 08:49:14
回答 2查看 1.1K关注 0票数 1

我有以下标记的联合界面

代码语言:javascript
复制
interface Example {
  a: TypeA;
  b: TypeB;
}

作为输出,我希望将此标记的联合转换为联合类型,如:

代码语言:javascript
复制
type oneOf<T> = ...

哪里

代码语言:javascript
复制
var example: oneOf(Example); // would be { a: TypeA } | { b : TypeB }

我无法将类型键映射到只有键作为参数的对象中。知道吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-26 09:27:48

您可以结合以下几种方法来完成:

代码语言:javascript
复制
interface Example {
  a: string;
  b: number;
}

type SingleProperty<T, K extends keyof T> = K extends any ? {[Prop in K]: T[Prop]} : never
type UnionOfProperties<T> = { [K in keyof T]: SingleProperty<T, K> }[keyof T];
type ExamplePropertiesUnion = UnionOfProperties<Example>

预期的回报如下:

代码语言:javascript
复制
type ExamplePropertiesUnion = {
    a: string;
} | {
    b: number;
}

虽然上面的内容是正确的,但TS将允许以下内容

代码语言:javascript
复制
var t: ExamplePropertiesUnion = {a: "", b: 42}

这不是我们通常想要的:

下面是更严格的类型检查的变体

代码语言:javascript
复制
type FixTsUnion<T, K extends keyof T> = {[Prop in keyof T]?: Prop extends K ? T[Prop]: never}
type oneOf<T> = { [K in keyof T]: Pick<T, K> & FixTsUnion<T, K>}[keyof T];
// ok
var z1: oneOf<Example> = { a: "" };
// ok
var z2: oneOf<Example> = { b: 5 };
// error
var z3: oneOf<Example> = { a: "", b: 34 };
// error
var z4: oneOf<Example> = { };

在这里试试

见问题:

票数 4
EN

Stack Overflow用户

发布于 2021-04-08 19:49:09

代码语言:javascript
复制
type EntryUnion<T> = { [K in keyof T]: { [Q in K]: T[Q] } }[keyof T];

这实际上与

代码语言:javascript
复制
type EntryUnion<T> = { [K in keyof T]: Pick<T, K> }[keyof T];

但是,每当我使用util类型(如 Pick )时,Intellij和VS代码中的类型推断就会停止,并且拒绝进一步扩展。尽管在转让人执行类型正确性时,他们做的工作完全相同,但当事情出错时,使用Pick的类型定义不正确的地方就不那么明显了(除非您非常熟悉Pick的功能)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62591230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档