我正在尝试编写具有以下类型签名的函数:
a
的类型为string
或undefined
b
也是string
,则a
是string
,否则是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'
}
}
我是否必须强制转换函数,还是可以说服打字机推断我的类型?
答案 0 :(得分:1)
Typescript不支持一个基于另一个的缩小参数。就编译器而言,a
和b
是独立的,并且检查a
不会影响b
的类型,即使条件类型在概念上将它们联系在一起。>
答案 1 :(得分:0)
重载该功能是解决此问题的方法。另外,请记住,在转换为JavaScript的过程中,所有TypeScript类型都会丢失。因此,条件键入实际上是不可能的,因为这将是运行时检查。您必须自己写那些支票。
最好将参数a移到第二个位置并使其可选,然后您可以编写干净的检查:
function myFunction(b: string | number, a?: string) {
if(typeof a !== "undefined") {
b = b as string;
b.split("");
}
}