我在 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"
}
}
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
(这些术语在 TypeScript 中的含义略有不同,但这里的区别并不重要)。Y
换句话说,如果我要一个
,fork
是一个可以接受的替代品,因为它具有与spork
相同的功能和属性(三个插脚和一个手柄)。fork
在为具有更多参数的函数键入的地方使用的函数可以安全地忽略额外的参数。例如:
let items = [1, 2, 3]; items.forEach(arg => console.log(arg));
这与“想要”错误的示例同构。在运行时,
使用三个参数(值、索引、数组)调用给定的回调,但大多数时候回调仅使用一两个参数。这是一种非常常见的 JavaScript 模式,必须显式声明未使用的参数会很麻烦。forEach
该 wiki 页面的其余部分有更多详细说明,如果您有兴趣,可以阅读。
根据我的基本实验,只有当您将“额外”参数设置为可选时,这才在 TypeScript 文件中可接受。引用上面链接的同一维基部分:
在 JavaScript 文件中,TypeScript 似乎并不关心,或者至少 VS Code 的内置 TypeScript 语言支持扩展并不关心。函数签名始终是从调用者的角度读取的。如果
声明其回调参数是可选的,则其含义是“forEach
可能会使用 0 个参数调用回调”。 [...]forEach
forEach
始终为其回调提供所有三个参数。您不必检查index
参数是否为undefined
- 它始终存在;这不是可选的。
请注意,从开发工具方面来看,如果调用函数的参数多于声明签名定义的参数,TypeScript 5.4 将提供快速修复建议,向函数添加参数。请参阅
相关发行说明部分。