为何TypeScript不对参数数量不符的传入函数发出警告?
在VS Code中搭建原生JavaScript项目并配置jsconfig.json后,遇到类型检查异常:
JavaScript示例代码:
/** * @param {(arg: string) => void} nestedFunction */ function myFunction(nestedFunction) { // Some logic here } myFunction("text"); // 错误被正确高亮 myFunction(() => {}); // 参数数量不足:未触发错误提示 myFunction((a, b) => {}); // 参数数量过多:未触发错误提示,且`a`类型为any
在TypeScript中定义相同函数时,也会出现完全一致的情况:
function myFunction(nestedFunction: (arg: string) => void) { // Some logic here }
VS Code能正确识别传入字符串这类类型不匹配的错误,但对参数数量不匹配的回调函数却不报错,这是为什么?
附项目的jsconfig.json配置:
{ "compilerOptions": { "checkJs": true, "target": "ES6" } }
这是TypeScript(包括开启checkJs后的JavaScript类型检查)的设计规则导致的,核心点如下:
贴合JavaScript运行特性:JS本身允许函数被调用时传入少于定义的参数(未传入的参数会被设为
undefined),也会自动忽略多余的参数。TypeScript为了兼容JS的实际运行逻辑,默认不对回调函数的参数数量不匹配情况报错。函数类型兼容性规则:TypeScript判断函数类型兼容时,默认允许“参数更少的函数”赋值给“参数更多的函数类型”——比如示例中的
() => {}可以被当作(arg: string) => void使用,因为调用时即使传入了string参数,这个回调也不会用到,不会引发运行错误。未标注参数的类型推断限制:当回调函数的参数没有显式标注类型时,TypeScript无法通过上下文推断出参数的具体类型,因此会将其默认设为
any。
如果想要启用更严格的检查,可以在jsconfig.json或tsconfig.json的compilerOptions中添加"strictFunctionTypes": true:
{ "compilerOptions": { "checkJs": true, "target": "ES6", "strictFunctionTypes": true } }
开启该选项后,参数数量不足的情况会被检测并报错,但参数过多的情况依旧不会报错(仍是为了兼容JS特性)。
内容的提问来源于stack exchange,提问作者Fede G

