打字稿错误优先回调输入(noImplicitAny、strictNullChecks)

oBu*_*usk 6 interface typing callback node.js typescript

我想在项目中使用带有和的typscript声明一个带有错误优先回调的函数。noImplicitAnystrictNullChecks

有没有办法声明 a interfaceortype允许两个不同的签名并在调用时工作?

最简单直接的方法就是这样声明

function example(callback: (err?: Error, result?: {data: any}) => void) {
    callback(undefined, {data: "hello"});
}
Run Code Online (Sandbox Code Playgroud)

但是,这允许我在callback()内部调用(不带参数),example这不是我们想要做的事情,因为回调应该始终以错误或结果调用。

function example(callback: (err: Error | undefined, result:  {data: any} | undefined) => void) {
    callback(undefined, {data: "hello"});
}
Run Code Online (Sandbox Code Playgroud)

这是不允许的example()。必须使用 2 个参数调用回调。

然而,这两种模式都意味着errresult可以是undefined。这并不完美,因为以下会导致错误。

example((err, result) => {
    if(err) { console.error(err); return; }

    console.log(result.data);
});
Run Code Online (Sandbox Code Playgroud)

由于result 可以undefined,我们不能想当然地认为它有属性data。为了解决这个问题,我要么必须在调用时断言第二个参数是某物example((err, result: {data: any}) => void),或者用resultin包装任何交互if(result)


我想声明的是,回调将永远被称为要么
callback(undefined, { data: "Hello" }) callback(Error, undefined)。这两个参数永远不会是未定义的。

我发现声明这一点的工作方式是

interface ICallback<r> {
    (err: undefined, result: r): void;
    (err: Error, result: undefined): void;
};

function example(callback: ICallback<{data: any}>) {
    callback(undefined, {data: "hello"});
}
Run Code Online (Sandbox Code Playgroud)

这似乎在内部起作用example,调用callback(new Error(), {data: "error"})callback(undefined, undefined)会导致错误。

然而; 当我使用这个example功能时;

example((err, result) => {
    ...
});
Run Code Online (Sandbox Code Playgroud)

这两个errresult隐式any。有什么方法可以声明允许(undefined, ISomething)(ISomethingElse, undefined)签名的回调函数,这意味着如果未定义 parameter1 ,我们可以期望定义 parameter2 ?

bas*_*rat 1

但是,允许我调用 example(() => void) 这并不是我真正想要的,因为我们至少应该处理错误。

情况永远如此。回调可以自由地忽略任何参数。

这是因为 TypeScript 的功能兼容性:https://basarat.gitbooks.io/typescript/content/docs/types/type-compatibility.html#number-of-arguments

更多的

在某种程度上,这类似于您可以随意忽略捕获异常。因此,如果需要的话,回调可以自由地忽略处理错误。