IHttpPromise 错误地使用 TypeScript 2.5 扩展 IPromise

2023-11-22

我开始使用 Typescript 2.5,现在我在 Angular Typescript 定义文件中收到以下代码消息:

interface IHttpPromise<T> extends IPromise<T> {
    success(callback: IHttpPromiseCallback<T>): IHttpPromise<T>;
    error(callback: IHttpPromiseCallback<any>): IHttpPromise<T>;
    then<TResult>(successCallback: (response: IHttpPromiseCallbackArg<T>) => IPromise<TResult>, errorCallback?: (response: IHttpPromiseCallbackArg<any>) => any): IPromise<TResult>;
    then<TResult>(successCallback: (response: IHttpPromiseCallbackArg<T>) => TResult, errorCallback?: (response: IHttpPromiseCallbackArg<any>) => any): IPromise<TResult>;
}

现在收到一条错误消息:

Severity    Code    Description Project File    Line    Suppression State Error TS2430  (TS) Interface 'IHttpPromise<T>' incorrectly extends interface 'IPromise<T>'.   Types of property 'then' are incompatible.
    Type '{ <TResult>(successCallback: (response: IHttpPromiseCallbackArg<T>) => IPromise<TResult>, errorCa...' is not assignable to type '{ <TResult>(successCallback: (promiseValue: T) => IHttpPromise<TResult>, errorCallback?: (reason:...'.
      Types of parameters 'successCallback' and 'successCallback' are incompatible.
        Types of parameters 'promiseValue' and 'response' are incompatible.
          Type 'IHttpPromiseCallbackArg<T>' is not assignable to type 'T'.  admin   C:\H\admin\admin\lib\typings\angularjs\angular.d.ts 1273    Active

有谁知道可能出了什么问题吗?将不胜感激您提供的任何建议。

作为参考,这里有 IPromise:

interface IPromise<T> {
    /**
     * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected.
     *
     * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method.
     */
    then<TResult>(successCallback: (promiseValue: T) => IHttpPromise<TResult>, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise<TResult>;
    /**
     * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected.
     *
     * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method.
     */
    then<TResult>(successCallback: (promiseValue: T) => IPromise<TResult>, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise<TResult>;
    /**
     * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected.
     *
     * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method.
     */
    then<TResult>(successCallback: (promiseValue: T) => TResult, errorCallback?: (reason: any) => TResult, notifyCallback?: (state: any) => any): IPromise<TResult>;

    /**
     * Shorthand for promise.then(null, errorCallback)
     */
    catch<TResult>(onRejected: (reason: any) => IHttpPromise<TResult>): IPromise<TResult>;
    /**
     * Shorthand for promise.then(null, errorCallback)
     */
    catch<TResult>(onRejected: (reason: any) => IPromise<TResult>): IPromise<TResult>;
    /**
     * Shorthand for promise.then(null, errorCallback)
     */
    catch<TResult>(onRejected: (reason: any) => TResult): IPromise<TResult>;

    /**
     * Allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information.
     *
     * Because finally is a reserved word in JavaScript and reserved keywords are not supported as property names by ES3, you'll need to invoke the method like promise['finally'](callback) to make your code IE8 and Android 2.x compatible.
     */
    finally<TResult>(finallyCallback: () => any): IPromise<TResult>;
}

您提供的代码表明您拥有旧版本的 Angular 类型文件。这个版本确实错误地(在 Typescript 2.4+ 看来)扩展IPromise<T>,因此与 v2.4+ 不兼容。

回调参数的严格逆变

Typescript 在 2.4.0 中“加强”了回调函数参数的类型检查,并在 2.4.2 中做了进一步的改进。这记录在“Typescript (2.4) 中的新增功能”wiki,并在“重大变化”2.4 页。

在编译器错误堆栈的底部,确实有意义IHttpPromiseCallbackArg<T>不可分配给T。因此,您拥有的类型文件在这方面始终是“不正确的”,但编译器在 v2.4 之前还不够智能,无法识别它。

插图

The Mappable<T> example非常类似于IPromise.then()。我们可以通过扩展接口来适应这个示例:

interface Mappable<T> {
    map<U>(f: (x: T) => U): Mappable<U>;
}

type R = {};

interface SubMappable<T> extends Mappable<T> {
    map<U>(f: (x: R) => U): Mappable<U>;
}

这段代码可以在 Typescript 2.3.3 上正常编译。 Typescript 2.4 将(理所当然地)抱怨 R 不可分配给 T。


正如我所提到的,这个示例(本质上)在结构上与(的精简版本)相同IPromise.then()。我们可以重命名函数、接口、参数和类型,给出:

interface MyPromise<T> {
    then<TResult>(successCallback: (promiseValue: T) => TResult): MyPromise<TResult>;
}

type R = {};

interface MyHttpPromise<T> extends MyPromise<T> {
    then<TResult>(successCallback: (response: R) => TResult): MyPromise<TResult>;
}

同样,Typescript 2.3.3 或更早版本将接受此代码,而 Typescript 2.4+ 则不会。替代IHttpPromiseCallbackArg<T> for R产生相同的结果。

The Fix

安装一个较新的类型文件.

相对较新的打字文件将具有IHttpPromise<T>定义为

interface IHttpPromise<T> extends IPromise<IHttpPromiseCallbackArg<T>> {   }

or

type IHttpPromise<T> = IPromise<IHttpResponse<T>>;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IHttpPromise 错误地使用 TypeScript 2.5 扩展 IPromise 的相关文章

随机推荐