错误 TS2345:类型为“(response: string) => void”的参数无法分配给类型“((value: {}) => void | PromiseLike<void>) | null”。

3

我通过npm更新了我的typescript包,现在出现了以下错误:

"TS2345: 类型为'(response: string) => void'的参数无法分配给类型为'((value: {}) => void | PromiseLike) | null | undefined'的参数"

尝试编译以下代码时出现以上错误:

private _send<T>(urlPath: string, params?: RequestParams): Promise<T> {
    return this._requester.sendRequest<T>(this._datafeedURL, urlPath, params);
}

public getServerTime(callback: ServerTimeCallback): void {
    this._send('time')
        .then((response: string) => {
            const time = parseInt(response);
            if (!isNaN(time)) {
                callback(time);
            }
        })
        .catch((error?: string | Error) => {
            logMessage(`Failed to load server time, error=${getErrorMessage(error)}`);
        });
}

错误来自.then这行代码。
我已经阅读了其他类似的问题,但是对于我的情况,我无法理解问题所在。

你能展示一下 _send 方法的具体实现吗?或者至少它的返回类型是什么? - CRice
1
谢谢,但现在我们需要更深入的了解。Typescript 无法推断 T 的类型,因此它会得到一个默认类型为 {}(太宽泛,导致您看到的问题)。为了了解为什么推断不起作用,我们需要知道 this._requester.sendRequest 的签名。this._requester 的类型是什么,如果可能的话,您能否发布其 sendRequest 方法的代码?或者如果它来自库,您能告诉我们是哪个库吗? - CRice
2
看起来你应该这样写:this._send<string>('time') - jcalz
1个回答

4

签名

_send<T>(urlPath: string, params?: RequestParams): Promise<T>;

takes返回一个Promise<T>,它有一个then()方法,其第一个参数是一个回调函数,该回调函数接受一个T类型的参数。如果您不知道 promises 是什么,请阅读有关它们的内容。五秒钟的解释是,Promise<Foo>是一个对象,在未来某个时间点将最终持有一个Foo对象,并且您可以使用then()方法告诉它当它最终获取到这个Foo对象时应该怎么做。

由于您正在使用以string为参数的回调函数调用then(),因此您需要使T可以分配给string。 最简单的方法是使T就是string

那么,你需要怎样使用 _send() 才能使 T 等于 string 呢?注意,无论是 urlPath 还是 params 都不依赖于 T。这意味着编译器几乎无法推断出任何 T 的值。看起来它默认为空对象类型 {},当 TypeScript 无法为类型参数推断任何值时,通常会发生这种情况。类型参数推断(请参阅 泛型手册部分 并查找“类型参数推断”以获取更多信息)不会发生。
因此,你只能通过显式指定类型参数来解决问题,方法是调用:
this._send<string>('time')

这样做应该可以让你的then调用成功编译。请注意,通过显式设置类型参数Tstring,您相信异步调用将在运行时实际返回一个string。虽然_send()的签名似乎保证它将为调用者指定的T的任何值返回一个Promise<T>,但在运行时它显然无法真正做到这一点。所以要小心。希望这对你有所帮助。祝好运!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接