【问题标题】:Typescript narrow parameter type based on discriminator基于鉴别器的Typescript窄参数类型
【发布时间】:2021-12-12 16:19:53
【问题描述】:

我有一个旧版 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参数进行类型检查?

谢谢

【问题讨论】:

  • 你能展示一些execute()被正确调用的例子吗?不清楚您打算如何将Command 的属性映射到args 参数。
  • 参见@tokland 的回答,他成功了

标签: typescript type-safety


【解决方案1】:

使用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 })

【讨论】:

  • 太棒了,谢谢。以前没有遇到过Extract。 Playground
【解决方案2】:

为此使用带有泛型的交集类型怎么样?我假设其余代码与您的示例相同:

function execute<T extends Command["cmd"]>(cmd: T, args: Command & { cmd: T }) {
    console.log(cmd, args)
}

我想不出更好的方法将鉴别器和Command 的正确类型“粘合”在一起。

【讨论】:

  • 无法让它正常工作,但谢谢。查看@tokland 的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2022-01-16
  • 2011-03-31
  • 2017-05-12
  • 2018-08-28
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多