typescript 从其中一个

djp7away  于 12个月前  发布在  TypeScript
关注(0)|答案(1)|浏览(136)

我有一个A型的:

type OneOf =
  | {
      $case: 'one';
      one: One;
    }
  | {
      $case: 'two';
      two: Two;
    }
  | {
      $case: 'three';
      three: Three;
    };

字符串
我想创建一个新的类型,能够从输入OneOf中获取,获取输出One | Two | Three
我尝试了很多不同的方法,包括从this answerUnionToIntersection的方法,希望通过一个交集,我可以简单地排除$case,在键上循环并返回类型。
我总是得到一个never类型作为输出。
基本上,我认为我可以通过以下方式摆脱它:

type ExtractOneOfTypes<T, K extends keyof T = keyof T> = {
  [key in K]: T extends { $case: key } ? T[key] : never;
}[K];


因为在我的oneOf中,对于每个$case,在同一个对象上,有一个属性名称与$case值相同。但这不起作用。有什么想法吗?

cclgggtu

cclgggtu1#

您可以infer$case的文字值类型,然后使用嵌套的Conditional Type检查它是否是keyof T,如下所示:

type One = { one: string };
type Two = { two: number };
type Three = { three: boolean };

type OneOf =
  | { $case: "one"; one: One }
  | { $case: "two"; two: Two }
  | { $case: "three"; three: Three };

type ExtractOneOfTypes<T, K extends keyof T> = T extends { [Key in K]: infer U }
  ? U extends keyof T
    ? T[U]
    : never
  : never;

type ExtractedType = ExtractOneOfTypes<OneOf, "$case">;
//    ^? type ExtractedType = One | Two | Three

字符串
TypeScript Playground

相关问题