Typescript基于鉴别器的窄参数类型
Typescript narrow parameter type based on discriminator
我有一个遗产 API 如下所示 (playground link)...
type Command1 = {
cmd: "my first command",
arg1: string,
arg2: boolean
}
type Command2 = {
cmd: "my second command",
foo: string,
bar: number
}
type Command = Command1 | Command2
function execute(cmd: Command["cmd"], args:any /* would like to strongly type this */) {
console.log(args)
}
execute("my first command", {/* oops missing props */})
有没有什么方法可以在不更改函数参数列表的情况下对 execute
函数的 args
参数进行类型检查?
谢谢
为此使用带有泛型的交集类型怎么样?我假设其余代码与您的示例相同:
function execute<T extends Command["cmd"]>(cmd: T, args: Command & { cmd: T }) {
console.log(cmd, args)
}
我想不出更好的方法将鉴别器和 Command
的正确类型“粘合”在一起。
使用Extract<Type, Union> (playground):
function execute<Cmd extends Command["cmd"]>(
cmd: Cmd,
args: Omit<Extract<Command, { cmd: Cmd }>, "cmd">
) {
console.log(cmd, args)
}
// execute<"my first command">(cmd: "my first command", args: Omit<Command1, "cmd">): void
execute("my first command", { arg1: "ksd", arg2: true })
// execute<"my second command">(cmd: "my second command", args: Omit<Command2, "cmd">): void
execute("my second command", { foo: "qwe", bar: 123 })
我有一个遗产 API 如下所示 (playground link)...
type Command1 = {
cmd: "my first command",
arg1: string,
arg2: boolean
}
type Command2 = {
cmd: "my second command",
foo: string,
bar: number
}
type Command = Command1 | Command2
function execute(cmd: Command["cmd"], args:any /* would like to strongly type this */) {
console.log(args)
}
execute("my first command", {/* oops missing props */})
有没有什么方法可以在不更改函数参数列表的情况下对 execute
函数的 args
参数进行类型检查?
谢谢
为此使用带有泛型的交集类型怎么样?我假设其余代码与您的示例相同:
function execute<T extends Command["cmd"]>(cmd: T, args: Command & { cmd: T }) {
console.log(cmd, args)
}
我想不出更好的方法将鉴别器和 Command
的正确类型“粘合”在一起。
使用Extract<Type, Union> (playground):
function execute<Cmd extends Command["cmd"]>(
cmd: Cmd,
args: Omit<Extract<Command, { cmd: Cmd }>, "cmd">
) {
console.log(cmd, args)
}
// execute<"my first command">(cmd: "my first command", args: Omit<Command1, "cmd">): void
execute("my first command", { arg1: "ksd", arg2: true })
// execute<"my second command">(cmd: "my second command", args: Omit<Command2, "cmd">): void
execute("my second command", { foo: "qwe", bar: 123 })