功能参数类型取决于其他参数的类型

时间:2019-02-12 12:53:47

标签: typescript typescript-typings

我正在尝试编写具有以下类型签名的函数:

  • 参数a的类型为stringundefined
  • 如果b也是string,则
  • 参数astring,否则是number

到目前为止,我的方法是:

function myFunction<X extends string | undefined>(
    a: X,
    b: X extends undefined ? number : string,
) {
    // ... do stuff ...
}

呼叫myFunction的工作与预期的一样,即。 myFunction('a', 'b')起作用,而myFunction(undefined, 'b')引发错误。但是,当我尝试使用函数体中的参数时,我没有任何键入支持:

function myFunction<...>(...) {
    if (a !== undefined) {
        // a is a string -> b must also be a string
        b.split(''); // -> Property 'split' does not exist on type 'X'
    }
}

我是否必须强制转换函数,还是可以说服打字机推断我的类型?

编辑:完整示例:https://typescript-play.js.org/#code/GYVwdgxgLglg9mABAWwJ4DFzXmAPADUQFMAPKIsAEwGdFqoAnGMAc0QB9FxKjhmjKAPgAUAKEQTEAQwBcifABpxkgEZzCpclVrde-SogD8iMCGQqiDRHPpNWSgJSIA3sokxgiYVMQBCALz+XFR6YAJOrpJRiAD0MdKIMLQ+tsxsALSCiCooIPTSADbUcNlECamsbtEqAHTUAA4FMFDCAOStDgDcVQC+oj1AA

2 个答案:

答案 0 :(得分:1)

Typescript不支持一个基于另一个的缩小参数。就编译器而言,ab是独立的,并且检查a不会影响b的类型,即使条件类型在概念上将它们联系在一起。

答案 1 :(得分:0)

重载该功能是解决此问题的方法。另外,请记住,在转换为JavaScript的过程中,所有TypeScript类型都会丢失。因此,条件键入实际上是不可能的,因为这将是运行时检查。您必须自己写那些支票。

最好将参数a移到第二个位置并使其可选,然后您可以编写干净的检查:

function myFunction(b: string | number, a?: string) {
    if(typeof a !== "undefined") {
        b = b as string;

        b.split("");
    }
}