我想使用带有noImplicitAny
和strictNullChecks
的typscript在项目中声明一个带有错误优先回调的函数。
有没有办法声明interface
或type
允许两个不同的签名并在调用时有效?
最简单,最直接的方法是将其声明为
function example(callback: (err?: Error, result?: {data: any}) => void) {
callback(undefined, {data: "hello"});
}
然而,这允许我在callback()
内调用example
(没有参数),这不是我们想要做的事情,因为应始终使用错误或结果调用回调。 / p>
function example(callback: (err: Error | undefined, result: {data: any} | undefined) => void) {
callback(undefined, {data: "hello"});
}
这不允许example()
。必须使用2个参数调用回调。
然而,这两种模式都意味着err
和result
都可以undefined
。这并不完美,因为以下内容会导致错误。
example((err, result) => {
if(err) { console.error(err); return; }
console.log(result.data);
});
由于result
可以undefined
,我们不能假设它具有属性data
。要解决此问题,我必须断言第二个参数是调用example((err, result: {data: any}) => void)
时的内容,或者在result
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"});
}
这似乎有效,在example
内,调用callback(new Error(), {data: "error"})
或callback(undefined, undefined)
会导致错误。
然而;当我然后使用这个example
函数时;
example((err, result) => {
...
});
err
和result
都隐含any
。有没有办法声明允许(undefined, ISomething)
或(ISomethingElse, undefined)
签名的回调函数,这意味着如果参数1未定义,我们可以期望定义参数2?
答案 0 :(得分:1)
然而,允许我调用example(()=&gt; void)这不是我想要的东西,因为我们应该处理至少错误。
情况总是如此。回调可以忽略任何参数。
这是因为TypeScript的功能兼容性:https://basarat.gitbooks.io/typescript/content/docs/types/type-compatibility.html#number-of-arguments
在某种程度上,这类似于您可以自由地忽略捕获异常的方式。因此,如果需要,回调可以忽略处理错误。
答案 1 :(得分:0)
我最接近的是:
interface NodeCallback<T> {
(err: any, result?: undefined | null): void;
(err: undefined | null, result: T): void;
}
对于cb: NodeCallback<string>
,这允许:
cb('boom')
,cb(new Error('boom'))
,cb('boom', null)
,cb('boom', undefined)
,cb(null, 'box')
,cb(undefined, 'box')
但不是cb(new Error('boom'), 'box')
,cb(null, 123)
等
不幸的是,它只对消费者方面有好处(也就是调用回调的那个) - 在遇到过载签名时,打字稿将放弃上下文推断的参数类型(或者,等效地,签名):
// 'err' and 'result' have type 'any', which will error with --strict / --noImplicitAny
const cb: NodeCallback<number> = (err, result) => {};
幸运的是,有一个recently opened PR可以解决这个问题!