首页 > 解决方案 > 是否可以将广义类型转换为联合

问题描述

请告诉我是否可以在不手动指定特定值的情况下推断最后一种类型(任务)?

interface Action {
  move: number,
  eat: string
}

interface Task<A extends keyof Action> {
  action: A,
  value: Action[A],
}

type Tasks = Task<'move'> | Task<'eat'>;

标签: typescripttypescript-typings

解决方案


您可以创建一个“人为的”分布式条件类型Task,以便为每个键创建一个联合类型Action。所以你不需要Task<"move"> | ... | Task<"other Action keys">手动设置:

type DesiredTasks = keyof Action extends infer I ? I extends keyof Action ? Task<I> : never : never
// type DesiredTasks = Task<"move"> | Task<"eat"> 
// same as { action: "move"; value: number; } | { action: "eat"; value: string; }

为什么不Task<keyof Action>呢?

所有属性值类型都合并在一起,例如可区分的联合类型将不再起作用:

type Tasks = Task<keyof Action> // {action: "move" | "eat"; value: string | number; }

declare const t1: Tasks
if (t1.action === "eat") t1.value // value: string | number, no good...

declare const t2: DesiredTasks
if (t2.action === "eat") t2.value // value: string ✔

示例 TS 游乐场


推荐阅读