IHttpPromise使用TypeScript 2.5错误地扩展了IPromise

时间:2017-12-22 07:20:10

标签: javascript angular typescript

我开始使用Typescript 2.5,现在我收到了Angular打字稿定义文件中代码的消息:

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>;
}

1 个答案:

答案 0 :(得分:11)

您提供的代码位表明您已获得Angular typings文件的旧版本。这个版本确实错误地(在Typescript 2.4+的眼中)扩展IPromise<T>,因此与v2.4 +不兼容。

回调参数严格违反

打字稿&#34;收紧&#34; 2.4.0中的回调函数参数的类型检查,并在2.4.2中做了进一步的改进。这在"What's new in Typescript (2.4)" wiki以及"Breaking changes"页面上记录为2.4。

在编译器错误堆栈的底部,IHttpPromiseCallbackArg<T>无法分配给T,这是有意义的。因此,您拥有的打字文件一直是&#34;不正确&#34;在这方面,但编译器不够聪明,直到v2.4才能识别它。

<强>插图

Mappable<T> exampleIPromise.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>替换为R会产生相同的结果。

修复

安装newer types file

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

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

type IHttpPromise<T> = IPromise<IHttpResponse<T>>;