当函数使用与预期不同数量的参数时,为什么 TypeScript 不发出警告?

问题描述 投票:0回答:1

我在 VS Code 中有一个普通的 JavaScript 项目,设置了

jsconfig.json
和以下示例代码:

/**
 * @param {(arg: string) => void} nestedFunction
 */
function myFunction(nestedFunction) {
  // Some logic here
}

myFunction("text");       // Error gets highlighted
myFunction(() => {});     // Fewer arguments: error doesn't get highlighted
myFunction((a, b) => {}); // More arguments: error doesn't get highlighted and "a" is of type "any"

如果我像这样定义函数,在 TypeScript 文件中也会发生同样的情况:

function myFunction(nestedFunction: (arg: string) => void) {
  // Some logic here
}
当向

myFunction

(字符串)传递错误类型的参数时,
VS Code 会正确突出显示错误,但在传递与
nestedFunction
格式不匹配的函数时,它不会抱怨。为什么?

如果需要,

jsconfig.json
文件如下:

{
  "compilerOptions": {
    "checkJs": true,
    "target": "ES6"
  }
}
javascript typescript visual-studio-code jsdoc
1个回答
3
投票

VS Code 中的 JavaScript 和 TypeScript 支持来自内置的 TypeScript 语言功能扩展,它只是基于 TypeScript 构建的。

当您使用参数少于“预期”的函数时

我认为这是一个案例 https://github.com/microsoft/TypeScript/wiki/FAQ#why-are-functions-with-fewer-parameters-assignable-to-functions-that-take-more-parameters ,其中指出:

这是预期和期望的行为。首先,请参阅常见问题解答顶部的“可替代性”入门知识

我认为所指的“可替代性引物”是this,其中指出:

许多与类型系统相关的答案都提到了可替代性。这是一个原则,如果一个对象

X
可以用来代替某个对象
Y
,那么
X
就是
Y
的子类型。我们通常还说
X
可以分配给
Y
(这些术语在 TypeScript 中的含义略有不同,但这里的区别并不重要)。

换句话说,如果我要一个

fork
spork
是一个可以接受的替代品,因为它具有与
fork
相同的功能和属性(三个插脚和一个手柄)。

在为具有更多参数的函数键入的地方使用的函数可以安全地忽略额外的参数。例如:

let items = [1, 2, 3];
items.forEach(arg => console.log(arg));

这与“想要”错误的示例同构。在运行时,

forEach
使用三个参数(值、索引、数组)调用给定的回调,但大多数时候回调仅使用一两个参数。这是一种非常常见的 JavaScript 模式,必须显式声明未使用的参数会很麻烦。

该 wiki 页面的其余部分有更多详细说明,如果您有兴趣,可以阅读。

当您使用参数多于“预期”的函数时

根据我的基本实验,只有当您将“额外”参数设置为可选时,这才在 TypeScript 文件中可接受。引用上面链接的同一维基部分:

函数签名始终是从调用者的角度读取的。如果

forEach
声明其回调参数是可选的,则其含义是“
forEach
可能会使用 0 个参数调用回调”。 [...] forEach
 始终为其回调提供所有三个参数。您不必检查 
index
 参数是否为 
undefined
 - 它始终存在;这不是可选的。

在 JavaScript 文件中,TypeScript 似乎并不关心,或者至少 VS Code 的内置 TypeScript 语言支持扩展并不关心。

请注意,从开发工具方面来看,如果调用函数的参数多于声明签名定义的参数,TypeScript 5.4 将提供快速修复建议,向函数添加参数。请参阅

相关发行说明部分

© www.soinside.com 2019 - 2024. All rights reserved.