为什么在这种情况下缩小类型会失败?

时间:2018-08-24 05:30:37

标签: typescript

给出:

export type CommandsTypes = {
  "test-command": {
    propA: string;
    propB: number;
  };

  "test-command2": {
    propC: string;
    propD: number;
  };
};

export type Command<K extends keyof CommandsTypes> = {
  type: K;
  payload: CommandsTypes[K];
};

export type AnyCommand = Command<keyof CommandsTypes>;

为什么以下内容没有按预期变窄:

function handle(command: AnyCommand) {
  if (command.type === "test-command") {
    // I would expect the type of command at this point to be
    // Command<"test-command"> 
    // But its not?
  }
}

任何想法都解释为什么Typescript无法将上面的AnyCommand类型缩小到 Command<"test-command">吗?

1 个答案:

答案 0 :(得分:1)

Command<keyof CommandTypes>等同于{ type: keyof CommandTypes, payload :CommandTypes[keyof CommandTypes] },这基本上意味着您可以将任何类型与任何有效负载配对,这不是您想要的。

您想建立一个有区别的工会。为此,我们可以使用条件类型的分布行为,该行为将对键联合的每个成员应用类型转换

export type AnyCommandHelper<T extends keyof CommandsTypes> =
    T extends keyof CommandsTypes? Command<T>: never
export type AnyCommand = AnyCommandHelper<keyof CommandsTypes>;