给出:
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">
吗?
答案 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>;