Typescript 元组联合类型的控制流分析
有没有一种方法可以告诉typescript,在下面的示例中,一个并集类型的元组可以满足任何代码路径的类型约束,而无需在函数体中手动指定每种情况Typescript 元组联合类型的控制流分析,typescript,functional-programming,tuples,Typescript,Functional Programming,Tuples,有没有一种方法可以告诉typescript,在下面的示例中,一个并集类型的元组可以满足任何代码路径的类型约束,而无需在函数体中手动指定每种情况 type options = [string, (a:string) => number] | [number, (b:number) => string ] function f( [input,fn]: options) { // Error: Cannot invoke an expression which
type options =
[string, (a:string) => number]
| [number, (b:number) => string ]
function f( [input,fn]: options) {
// Error: Cannot invoke an expression which lacks a call signature
return fn(input)
}
如果输入
是一个字符串
,fn
将接受一个字符串
,如果输入
是一个数字
,fn
将接受一个数字
。然而,Typescript认为fn
无法接受输入,因为它认为它是string | number
可能的函数为(string)=>number |(number)=>string
,其中输入为string | number
。如果函数接受(string | number)=>number |(string | number)=>string
typescript,它就可以了。但是我想告诉Typescript,没有任何可能的方法fn
不能接受arg
(这是真的)
我理解为什么Typescript确定各个类型不兼容。但是我正在寻找一种方法来告诉typescript,每个可能的元组都是自包含的,并且可以用自己的函数调用自己的参数。这里有一种类型安全的方法来让它工作。
as
关键字不是强制转换,如果类型不兼容,它会抱怨
type options =
[string, (a:string) => number]
| [number, (b:number) => string ]
function f( [input,fn]: options) {
return (fn as (a: string | number) => string | number)(input);
}
TypeScript本身不够聪明,无法解决这个问题,因此它需要一些帮助,将类型稍微加宽一点。对我来说似乎是正确的行为
f
接受一个元组,而你正试图给它一个字符串或数字?你的意思是做一个递归调用,应该f(输入)
是fn(输入)
?我想他会的,因为最后一段提到的是fn
,而不是f
。这不是问题中的打字错误,因为他得到的错误是你调用f
时会得到的错误。我修改了我的回答以反映这一意图。不过,由于某种相当复杂的类型理论,修复该缺陷仍将失败。我想知道这是一个玩具示例,还是您真正想要使用的东西?这是我想要用来键入调用REST端点可能接受的参数的东西@SimonMeskensYes,因为这是一个完全不同的例子。请注意,在最初的问题中,他是递归调用,而不是调用回调。也许这是他自己的错误,我会修改我的回答重新编写答案以适应问题。我真的希望避免枚举函数体中所有可能的类型。我认为即使将fn转换为任何也是类型安全的,因为它将在调用级别受到保护。这样就避免了函数体中的枚举。它不会完全是类型安全的,但是调用点应该是类型安全的。