Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 元组联合类型的控制流分析_Typescript_Functional Programming_Tuples - Fatal编程技术网

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

有没有一种方法可以告诉typescript,在下面的示例中,一个并集类型的元组可以满足任何代码路径的类型约束,而无需在函数体中手动指定每种情况

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转换为任何
也是类型安全的,因为它将在调用级别受到保护。这样就避免了函数体中的枚举。它不会完全是类型安全的,但是调用点应该是类型安全的。