typescript中是否有方法确保函数';输入签名与输出签名相同?

typescript中是否有方法确保函数';输入签名与输出签名相同?,typescript,Typescript,函数需要另一个泛型函数作为输入,其定义如下: function higherOrderFunction(fn: Function): Function { // do something return (...args: any[]) => fn(...args); } 称为 function fun(x: number, y: string) { return `${x}${+y}`; } const higherOrderFunctionWithFunction= hig

函数需要另一个泛型函数作为输入,其定义如下:

function higherOrderFunction(fn: Function): Function {
  // do something
  return (...args: any[]) => fn(...args);
} 
称为

function fun(x: number, y: string) { return `${x}${+y}`; }

const higherOrderFunctionWithFunction= higherOrderFunction(fun);
console.log(higherOrderFunctionWithFunction(1, '3'))
这将在typescript中工作(无编译错误),无论是x还是y类型

只有当
x:number,y:string
时,TSC才能正确编译
higherOrderFunction
返回的函数?(理想情况下,对于任何数量的参数和类型,而不仅仅是这种特定情况)

最终实现了目标

higherOrderFunction
需要重构为:

function higherOrderFunction<A extends any[], B>(fn: (...a: A) => B) {
  return (...args: A) => fn(...args);
}
会扔

类型为“3”的参数不能分配给类型为“string”的参数

它有效地强制低阶函数(
fun
)的签名(传递到高阶函数并从中返回)完全相同


如果
fun
接收到超过2个参数(其类型在
fun
中指定)

可能我没有遵循,但如果高阶函数返回一个带有任何参数的函数,则调用时将返回传入函数的结果,传递参数-不能直接返回传入的函数吗?然后,泛型输入非常简单,我看不出您还需要输入什么

function higherOrderFunction<T>(fn: T): T {
  // do something
  return fn;
} 

function fun(x: number, y: string) { return `${x}${+y}`; }

const higherOrderFunctionWithFunction = higherOrderFunction(fun);
console.log(higherOrderFunctionWithFunction(1, 3)) // error can't assign number to string
函数高级命令函数(fn:T):T{
//做点什么
返回fn;
} 
函数fun(x:number,y:string){return`${x}${+y}`;}
const higherOrderFunction with function=higherOrderFunction(乐趣);
log(higherOrderFunctionWithFunction(1,3))//错误无法为字符串分配编号
编辑:

如果你的高阶函数是下面的,那么这会改变情况,我会改变我的答案。但是你有//在返回之前做一些事情,所以离开你的例子,看起来你也可以返回fn

function higherOrderFunction<T>(fn: T): T {
  return (...args) => {
      // do something common on every call
      return fn(...args);
  };
} 
函数高级命令函数(fn:T):T{
返回(…参数)=>{
//每次打电话都要做些平常的事
返回fn(…args);
};
} 
编辑2: 对于上面的场景,如果您真的需要在另一个函数中封装fn,那么这是我能够获得您正在寻找的类型检查的唯一方法,没有其他错误。我必须使用类型断言来返回高阶函数,以断言T正在被返回,并且它没有被实例化为不同的子类型。。。不能说我100%理解这个具体案例中的问题,但它与此相关:

函数高级或函数未知>(fn:T):T{
返回((…参数)=>{
//每次打电话都要做些平常的事
返回fn(…args);
})as-T;
}
函数fun(x:number,y:string){return`${x}${+y}`;}
const higherOrderFunction with function=higherOrderFunction(乐趣);
log(higherOrderFunctionWithFunction(1,3))//错误无法为字符串分配编号
编辑3:
看看你的答案,我更喜欢它,我想你已经明白了…

type'(…args:any[])=>any'不能分配给type'T'T'可以用与“(…args:any[])=>any”无关的任意类型实例化。ts(2322)Rest参数“args”隐式具有“any[]”类型。使用
(…args:any[])
不会这样做吗?你指的是什么?我展示的第一个片段是一个根本不使用…args的解决方案,然后我用一个伪代码示例询问了一个关于需求的问题,该示例是有一个类型错误的,如果您尝试实际使用它,它只是一个示例,说明了//do something代码的实际用途。你能确认你将在哪里“做点什么”吗?高阶块还是在返回的函数中?OP在高阶块中有它-如果这是您计划//执行某些操作的地方-那么您不需要在fn周围使用包装函数。您需要在另一个函数中包装fn的唯一原因是,如果您想在调用fn时运行一些公共代码,这不是OP的读取方式。我可能应该澄清一下。高阶函数确实应该返回一个函数(…args)=>(公共代码)。重要的是,传递给高阶函数的fn可以强制执行fn参数(在我的问题中:x和y分别作为数字和字符串,但理想情况下fn可以有任意数量/类型的参数),这并没有阐明为什么需要返回另一个函数,这就是我所指出的——OP读取的方式是,您返回的函数实际上什么都不做,只是将参数传递给fn并返回结果。基于此,您不需要包装功能。如果你在这个函数中做了其他的事情,那么你应该在你的OP中说明这一点,这就是我要说的,让问题更清楚。
function higherOrderFunction<T>(fn: T): T {
  return (...args) => {
      // do something common on every call
      return fn(...args);
  };
} 
function higherOrderFunction<T extends (...args: any[]) => unknown>(fn: T): T  {
  return ((...args) => {
      // do something common on every call
      return fn(...args);
  }) as T;
}

function fun(x: number, y: string) { return `${x}${+y}`; }

const higherOrderFunctionWithFunction = higherOrderFunction(fun);
console.log(higherOrderFunctionWithFunction(1, 3)) // error can't assign number to string