如何检查传递给函数的参数数量是不是错误

Posted

技术标签:

【中文标题】如何检查传递给函数的参数数量是不是错误【英文标题】:How to check for wrong number of parameters passed to a function如何检查传递给函数的参数数量是否错误 【发布时间】:2016-11-26 09:22:44 【问题描述】:

我正在编写一个使用 typescript 和 tslint 作为 linter 的程序。 我目前最喜欢的规则列表如下(tslint.json):


    "extends": "tslint:recommended",

    "rules": 
        "comment-format": [false, "check-space"],
        "eofline": false,
        "triple-equals": [false, "allow-null-check"],
        "no-trailing-whitespace": false,
        "one-line": false,
        "no-empty": false,
        "typedef-whitespace": false,
        "whitespace": false,
        "radix": false,
        "no-consecutive-blank-lines": false,
        "no-console": false,
        "typedef": [true,
            "variable-declaration",
            "call-signature",
            "parameter",
            "property-declaration",
            "member-variable-declaration"
        ],
        "quotemark": false,
        "no-any": true,
        "one-variable-per-declaration": false
    


虽然我使用的是 Tslint,但它无法捕获对参数数量错误的函数的调用。 例如我有以下功能:

let displayTimer: Function = function(): void 
    document.getElementById('milliseconds').innerhtml = ms.toString();
    document.getElementById('seconds').innerHTML = seconds.toString();
    document.getElementById('minutes').innerHTML= minutes.toString();
;

我从另一个函数内部调用它:

let turnTimerOn: Function = function(): void 

    ms += interval;

    if (ms >= 1000)
    
        ms = 0;
        seconds += 1;
    

    if (seconds >= 60)
    
        ms = 0;
        seconds = 0;
        minutes += 1;
    

    displayTimer(1);
;

如您所见,我正在向 displayTimer 函数传递一个参数(在本例中为数字 1,但它可以是其他任何值)并且 linter 没有捕捉到它。

【问题讨论】:

好吧,那是因为它不是无效的javascript。传递未定义为参数的值并稍后在函数中使用 arguments 检索它们是完全有效的。 感谢您指出这一点。我来自 Java/C# 背景,所以我希望能够检查这种类型的不匹配。有什么想法吗? 也许我遗漏了一些东西,但函数没有声明为function displayTimer():void 有什么原因吗?我认为 TS 最好能够检查一下。现在打字的所有工作都是let displayTimer:Function = ???。它不知道你是否会在某个时候为它重新分配 null 或其他函数。 【参考方案1】:

只需删除类型 Function,TypeScript 就会检查签名:

let displayTimer = function(): void 
    // ...
;

displayTimer(1); // Error: Supplied parameters does not match any signature of call target

displayTimer 的推断类型不是Function(接受任何签名)而是() => void

见the code in the PlayGround。

【讨论】:

感谢您的回答。关于 typescript 编译器在我删除函数类型声明时检测到错误是正确的。问题是,一旦我删除声明,我就会看到这些 tslint 规则tslint 抱怨此删除(TSLint:预期变量声明:'displayTimer' to have a typedef (typedef)) 按照您的建议,我使用以下代码在同一行中声明和赋值。它有点难看,但它有效:let displayTimer: () => void = function(): void document.getElementById('milliseconds').innerHTML = ms.toString(); document.getElementById('seconds').innerHTML = seconds.toString(); document.getElementById('minutes').innerHTML= minutes.toString(); ; @skiabox IMO,您应该在可以使用的地方使用推理。 let displayTimer: () => void = function(): void /* ... */ 不是 DRY。 你能解释一下DRY这个词吗?谢谢! @skiabox Don't repeat yourself。也许你应该考虑TS编译器的编译选项noImplicitAny(see compilation options here)。

以上是关于如何检查传递给函数的参数数量是不是错误的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中如何正确地将 int 数组传递给函数

Flex:传递函数和检查参数

如何显式指定传递给函数的数组参数的大小

如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]

在 Kotlin Android 中将值传递给函数时进行编译时间检查

将参数列表传递给Python函数[重复]