【问题标题】:error TS2345: Argument of type '(response: string) => void' is not assignable to parameter of type '((value: {}) => void | PromiseLike<void>) | null错误 TS2345:“(响应:字符串)=> void”类型的参数不可分配给“((值:{})=> void | PromiseLike<void>)类型的参数 |空值
【发布时间】:2018-10-29 05:25:36
【问题描述】:

我通过 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方法体吗?或者至少它的返回类型是什么?
  • 谢谢,但现在我们需要更深入。 Typescript 无法推断T 的类型,因此它得到了{} 的默认类型(这太宽泛了,导致您看到的问题)。要了解为什么该推断不起作用,我们需要知道this._requester.sendRequest 的签名。 this._requester 的类型是什么,如果可能的话,你能发布它的sendRequest 方法的代码吗?或者如果它来自图书馆,你能告诉我们是哪一个吗?
  • 看来你应该说this._send&lt;string&gt;('time')

标签: typescript


【解决方案1】:

签名

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

takes 返回一个Promise&lt;T&gt;,它有一个then() 方法,其第一个参数是一个回调,它采用T 类型的参数。如果你不知道promises 是什么,你应该阅读它们。五秒钟的解释是,Promise&lt;Foo&gt; 是一个对象,它最终将在未来的某个时间持有Foo 对象,你告诉它(使用then() 方法)它应该如何处理@987654331 @object 当它最终得到它时。

由于您使用参数为string 的回调函数调用then(),因此您需要将T 分配给string。发生这种情况的最简单方法是T string

那么,要使T 等于string,您与_send() 有什么关系?请注意,urlPathparams 都不依赖于 T。这意味着编译器几乎无法推断出T 的任何值。看起来它默认为空对象类型{},当 TypeScript 无法推断类型参数的任何值时,往往会发生这种情况。类型参数推断(请参阅the Handbook section on generics 并查找“类型参数推断”以获取更多信息)不会发生。

您可以通过调用显式指定类型参数

this._send<string>('time')

这应该允许您的then 调用成功编译。请注意,通过将类型参数T 显式设置为string,您相信异步调用实际上会在运行时返回string_send() 的签名似乎确实保证它会为调用者指定的Tany 值返回一个Promise&lt;T&gt;,但显然它不能在运行时真正做到这一点。所以要小心。

希望对您有所帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2021-04-18
    • 2021-04-28
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2022-07-20
    相关资源
    最近更新 更多