函数上的Typescript调用签名作为参数

函数上的Typescript调用签名作为参数,typescript,function,call,Typescript,Function,Call,我正在尝试构建一个函数defaultArguments,它接受一个现有函数并使用新的输入更改其默认参数 var add = function (a: number, b: number) { return a + b; }; var defaultArguments = function( // func: (args: ReturnType<typeof func.arguments>) => void, func: Function, o

我正在尝试构建一个函数
defaultArguments
,它接受一个现有函数并使用新的输入更改其默认参数

var add = function (a: number, b: number) {
    return a + b;
};

var defaultArguments = function(
    // func: (args: ReturnType<typeof func.arguments>) => void, 
    func: Function,
    obj: Object) {
    let keys = Object.keys(obj);
    let alphabeth = "abcdefghijklmnopqrstuvwxyz";

    if (typeof func === "function") {
        for (let i: number = 0; i < func.arguments.length; i++) {
            for (let a = 0; a < keys.length; a++) {
                // Replace arguments according to alphabethic order
                let arr = [];
                arr.splice(alphabeth.indexOf(keys[a]), 0, keys[a]); // push value to position of letter in 'alphabeth'
                func.arguments[a] = arr[a];
            }
        }
        return func;

    } else { return "Cannot find function " + func['name'] };
};

const add2 = defaultArguments(add, { b: 9 });
console.assert(add2(10) === 19);
console.assert(add2(10, 7) === 17);
console.assert(isNaN(add2()));
var add=函数(a:number,b:number){
返回a+b;
};
var defaultArguments=函数(
//func:(args:ReturnType)=>void,
func:函数,
对象(对象){
设keys=Object.keys(obj);
让alphabeth=“abcdefghijklmnopqrstuvxyz”;
if(函数类型==“函数”){
for(设i:number=0;i
调用第二个命令
console.assert(add2(10)==19)
时,会出现以下错误:

无法调用其类型缺少调用签名的表达式。类型“string | Function”没有兼容的调用签名


就好像
const add2=defaultArguments(add,{b:9})
的ReturnType不是字符串的函数一样。

正如@jcalz在注释中指出的那样,方法
defaultArguments
要么返回
函数
要么返回
字符串

在编写代码的时候

console.assert(add2(10) === 19);
编译器正确地标记了一个错误,因为此时您不知道两种可能的类型
add2
是哪一种

如果在代码中添加额外的类型检查,编译器将确保您使用的是
function
类型的值,并且编译时不会出错

if (typeof(add2) === 'function')) {
  console.assert(add2(10) === 19);
  console.assert(add2(10, 7) === 17);
  console.assert(isNaN(add2()));
} else {
  console.error(add2);
}

快速回答是因为
defaultArguments()
返回
函数
字符串
。您有
else返回“Cannot”…
,因此编译器认为它可能返回字符串。在这种错误情况下,您可能应该
抛出
,而不是
返回
。但是,在修复之后,您仍然只有一个
函数
,它实际上不是类型安全的(它将接受所有参数并返回
任何
)。我真的不知道输入这样一个不寻常函数的最佳方法;返回的函数接受某种可选参数,尽管这些参数的位置以一种奇怪的方式取决于
obj
的键。但是你没有问,所以我想我不会尝试。真管用!现在,与此无关,编译器抛出另一个错误:
throw e;^TypeError:无法在defaultArguments(/Users/luca/Desktop/splyt tasks/splyt test.js:12:44)处读取null的属性“length”
显然它似乎无法读取
func
的属性
参数,因此在错误中为“null”。我错过什么了吗?如何确定函数参数的参数数组的范围?