为什么TypeScript在将函数参数传递给类型化函数时不推断函数参数类型?

为什么TypeScript在将函数参数传递给类型化函数时不推断函数参数类型?,typescript,types,Typescript,Types,在以下示例中: function functionA(x: string, y: number, z: SpecialType): void { } const functionWrapper: (x, y, z) => functionA(x, y, z); functionWrapper的参数类型为any。有什么办法可以解决这个问题吗 鼓励tsc根据其使用情况推断其类型?TypeScript类型系统的什么限制阻止了这一问题的解决?一个原因是:根据您的建议,如果TypeScript可以

在以下示例中:

function functionA(x: string, y: number, z: SpecialType): void { }
const functionWrapper: (x, y, z) => functionA(x, y, z);
functionWrapper的参数类型为
any
。有什么办法可以解决这个问题吗
鼓励tsc根据其使用情况推断其类型?TypeScript类型系统的什么限制阻止了这一问题的解决?

一个原因是:根据您的建议,如果TypeScript可以自动缩小签名范围,它将隐式地传播到所有呼叫站点,并导致这些站点失败

函数你的函数(x){
dosomethingthatakesanumber(x);
}
//别处
功能(1);
//还在别的地方
函数(-1);
一旦将
yourFunction
更改为
doSomethingthatakesBoolean
,Typescript将推断
x
必须是布尔值,然后两个不相关的调用将开始失败。这将特别难以调试

对于编写与所包装的函数具有相同签名的包装函数的情况,可以使用
typeof function
包装函数,而无需重复。Typescript可以从函数的类型推断参数的类型,但不能从函数体中表示的代码推断参数的类型

constfunctionwrapper2:typeof function=(x,y,z)=>function(x,y,z);

一个原因是:对于您的提议,如果Typescript可以自动缩小签名范围,它会隐式地传播到所有呼叫站点,并导致这些站点失败

函数你的函数(x){
dosomethingthatakesanumber(x);
}
//别处
功能(1);
//还在别的地方
函数(-1);
一旦将
yourFunction
更改为
doSomethingthatakesBoolean
,Typescript将推断
x
必须是布尔值,然后两个不相关的调用将开始失败。这将特别难以调试

对于编写与所包装的函数具有相同签名的包装函数的情况,可以使用
typeof function
包装函数,而无需重复。Typescript可以从函数的类型推断参数的类型,但不能从函数体中表示的代码推断参数的类型

constfunctionwrapper2:typeof function=(x,y,z)=>function(x,y,z);

类型脚本类型分析以自顶向下的方式工作。这意味着它等于程序数据流,其中的数据也是自上而下传递的。TypeScript正在分析控制流,但它使用的是从顶部提供的信息,而不是从底部提供的信息

考虑这样的函数示例:

function functionMaker(x: string, y: string) { 
    return () => x + y; 
}
上面的函数返回另一个函数。在返回的匿名函数的定义中没有明确的类型,但是TS能够分析
functionMaker
总是返回
()=>字符串
函数类型

以另一种方式这样做是不可能的,因为TS无法预测您将如何处理参数。考虑如下:

function functionA(x: string, y: number, z: SpecialType): void { }
function functionB(x: number): void { }
const functionWrapper: (x, y, z) => { 
  functionA(x, y, z);  // x should be string
  functionB(x); // x should be number
}
现在TS有两个使用一个参数的函数,但它们都有不同的类型要求。任何解决这个难题的方法都是错误的,因为一个或另一个函数将失败

总之,类型分析是自顶向下进行的。但我们可以通过创建泛型函数来解决您的问题,该函数将封装另一个泛型函数

function functionA(x: string, y: number, z: SpecialType): void { }

const wrap = <X, Y, Z, R>(f: (x: X, y: Y, z: Z) => R) => (x: X, y: Y, z: Z): R => f(x,y,z);
const functionWrapper = wrap(functionA);
函数functa(x:string,y:number,z:SpecialType):void{}
常数换行=(f:(x:x,y:y,z:z)=>R)=>(x:x,y:y,z:z):R=>f(x,y,z);
const functionWrapper=wrap(function);

我们的
wrap
被明确定义为一个包装器,这意味着它的目的是从给定函数推断类型,并创建另一个具有相同参数和相同返回的函数

TypeScript类型分析以自顶向下的方式工作。这意味着它等于程序数据流,其中的数据也是自上而下传递的。TypeScript正在分析控制流,但它使用的是从顶部提供的信息,而不是从底部提供的信息

考虑这样的函数示例:

function functionMaker(x: string, y: string) { 
    return () => x + y; 
}
上面的函数返回另一个函数。在返回的匿名函数的定义中没有明确的类型,但是TS能够分析
functionMaker
总是返回
()=>字符串
函数类型

以另一种方式这样做是不可能的,因为TS无法预测您将如何处理参数。考虑如下:

function functionA(x: string, y: number, z: SpecialType): void { }
function functionB(x: number): void { }
const functionWrapper: (x, y, z) => { 
  functionA(x, y, z);  // x should be string
  functionB(x); // x should be number
}
现在TS有两个使用一个参数的函数,但它们都有不同的类型要求。任何解决这个难题的方法都是错误的,因为一个或另一个函数将失败

总之,类型分析是自顶向下进行的。但我们可以通过创建泛型函数来解决您的问题,该函数将封装另一个泛型函数

function functionA(x: string, y: number, z: SpecialType): void { }

const wrap = <X, Y, Z, R>(f: (x: X, y: Y, z: Z) => R) => (x: X, y: Y, z: Z): R => f(x,y,z);
const functionWrapper = wrap(functionA);
函数functa(x:string,y:number,z:SpecialType):void{}
常数换行=(f:(x:x,y:y,z:z)=>R)=>(x:x,y:y,z:z):R=>f(x,y,z);
const functionWrapper=wrap(function);

我们的
wrap
被明确定义为一个包装器,这意味着它的目的是从给定函数推断类型,并创建另一个具有相同参数和相同返回的函数

我认为函数签名通常是不可推断的。如果你正在定义一个函数,那么就由你来指定它的签名。我认为函数签名通常是不可推断的。如果您正在定义一个函数,则由您指定其签名。