Typescript 如何从映射类型转换为有区别的联合

Typescript 如何从映射类型转换为有区别的联合,typescript,Typescript,如果已经问过这个问题,我表示歉意。我试图找到解决方案,但我可能没有用正确的术语进行搜索 我的问题从这个结构开始。这是一个简单的映射类型: type Mapped = { square: { size: number; }; rectangle: { width: number; height: number; }; }; 然后我有一个类型,它试图创建一个联合: type Unionize<T> = { name: keyof T; d

如果已经问过这个问题,我表示歉意。我试图找到解决方案,但我可能没有用正确的术语进行搜索

我的问题从这个结构开始。这是一个简单的映射类型:

type Mapped = {
  square: {
    size: number;
  };
  rectangle: {
    width: number;
    height: number;
  };
};
然后我有一个类型,它试图创建一个联合:

type Unionize<T> = {
  name: keyof T;
  data: T[keyof T];
};

type Out = Unionize<Mapped>;
但我真正想要的是这样,因为这样我就能够利用判别联合来推断和检查数据属性

type Wanted = {
  name: "square";
  data: {
    size: number;
  };
} | {
  name: "rectangle";
  data: {
    width: number;
    height: number;
  };
}

不要使用
keyof T
单独生成
名称
数据
类型,首先使用映射类型为
T
的每个键组合正确的
名称
数据
,然后通过
keyof T
对其进行索引以获得联合

type Unionize<T> = {
  [P in keyof T]: {
    name: P;
    data: T[P];
  }
}[keyof T];
类型联合={
[P in keyof T]:{
姓名:P,;
资料:T[P];
}
}[keyof T];

正确答案。。但也许可以解释一下为什么他的错而你的错。。。很难更新代码片段…(虽然我做了:-)当我怀疑OP需要它时,很难对编写解释充满热情,也很难怀疑其他有同样问题的人将来会找到这个线程。但我很无聊,所以在那里,我做到了你永远不知道谁会找到这些。。几个月前我回答了一个问题,我收到了所有的选票,我从来没想过有人会挖出来:)事实上@MattMcCutchen我真的很感谢你的解释。我一直在努力寻找自己。因此,尽管我非常感谢这个实际的解决方案,但背后的原因(我没有找到)更有趣@MattMcCutchen我意识到现在你基本上回答了同样的问题:。你说得对,很难找到。
type Unionize<T> = {
  [P in keyof T]: {
    name: P;
    data: T[P];
  }
}[keyof T];