没有参数的传递函数不会引发错误

我正在使用 TypeScript 4.3.5。在代码中,我需要传递一个函数,我需要检查该函数是否包含必需的参数。此代码不会引发语法错误:

function functionA (call: (name: string) => boolean) {
  call("")
}

function functionB () {
  return true;
}

function functionC() {
  functionA(functionB); // this doesn't throw a syntax error
  functionB(""); // this throws a syntax error
}

我也尝试过这种类型定义:

type FunctionB = {
  (name: string): boolean
}

没有任何效果。我希望 TypeScript 在调用时抛出语法错误,functionA(functionB)因为 functionB 不包含预期的参数。当我调用functionB("")它时会引发错误。

有什么解决方案可以在我调用时遇到语法错误functionA(functionB)吗?

回答

不,这是预期行为,您不能强制 TypeScript 在这种情况下抛出语法错误。

根据 TypeScript 的常见问题解答:

这是预期和期望的行为。首先, [...] [ functionB] 是[ ] 的有效参数,functionA因为它可以安全地忽略额外的参数。

其次,让我们考虑另一种情况:

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

这与“想要”错误的示例同构。在运行时,forEach 使用三个参数(值、索引、数组)调用给定的回调,但大多数时候回调只使用一两个参数。这是一种非常常见的 JavaScript 模式,必须显式声明未使用的参数会很麻烦。

但是 forEach 应该只将其参数标记为可选!例如forEach(callback: (element?: T, index?: number, array?: T[]))

这不是可选回调参数的含义。函数签名总是从调用者的角度读取。如果 forEach 声明其回调参数是可选的,则其含义是“forEach 可能会使用 0 个参数调用回调”。

可选回调参数的含义是这样的:

// Invoke the provided function with 0 or 1 argument
function maybeCallWithArg(callback: (x?: number) => void) {
    if (Math.random() > 0.5) {
        callback();
    } else {
        callback(42);
    } 
} 

forEach 总是为其回调提供所有三个参数。您不必检查 index 参数是否未定义 - 它始终存在;这不是可选的。

正如@Liad 的回答中所解释的那样,这种模式用于许多 JavaScript 函数,无论是原生的还是其他的(想想Array#forEach, Array#map, Array#reduce),并且要求函数的用户声明未使用的参数最多是“繁重的”,如常见问题条目中所述。

因此,只要它共享其返回类型并且不添加更多参数,functionB就可以分配给,但声明更少的参数不会引发错误。call

至于是否可以强制 TypeScript 编译器抛出语法错误,这也在前面提到的 FAQ 条目的底部解决:

目前在 TypeScript 中没有一种方法来指示必须存在回调参数。请注意,这种强制措施永远不会直接修复错误。换句话说,在一个假设的世界中,要求 forEach 回调至少接受一个参数,您将拥有以下代码:

[1, 2, 3].forEach(() => console.log("just counting"));
             //   ~~ Error, not enough arguments?

通过添加参数,这将是“固定的”,但不会变得更正确:

[1, 2, 3].forEach(x => console.log("just counting"));
               // OK, but doesn't do anything different at all

以上是没有参数的传递函数不会引发错误的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>