首页 > 解决方案 > 为什么在这种情况下类型缩小会失败?

问题描述

鉴于:

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">

标签: typescript

解决方案


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>;

推荐阅读