IHttpPromise Extends IPromise Incorrectly with TypeScript 2.5

I started using Typescript 2.5, and now I get this message for the code in the Angular Typescript definition file:

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

You will now receive the error message:

 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 

Does anyone have any ideas what might be wrong? Appreciate any advice you can give.

For reference: 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>; } 
+5
source share
1 answer

The code bits that you specified indicate that you have an older version of the Angular file. This version is really wrong (in the eyes of Typescript 2.4+) extends IPromise<T> and therefore is incompatible with v2.4 +.

Strict contravariance for callback parameters

Typescript "dragged on" type checking for callback function parameters in 2.4.0 and made further improvements in 2.4.2. This is described on the “What's New in Typescript (2.4)” wiki , and on “Breaking Changes” for 2.4.

At the bottom of the compiler error stack, it makes sense that IHttpPromiseCallbackArg<T> not assigned to T Thus, the typing file you have always been “wrong” in this regard, but the compiler was not smart enough to recognize it as such prior to version 2.2.

Illustration

Mappable<T> example is very similar to IPromise.then() . We can adapt this example by expanding the interface:

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

This code will be compiled using Typescript 2.3.3. Typescript 2.4 (rightfully) complains that R is not assigned T.


As I mentioned, this example is (essentially) structurally identical (with a reduced version) to IPromise.then() . We can rename functions, interfaces, parameters, and types by specifying:

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

Again, Typescript 2.3.3 or earlier will accept this code, but Typescript 2.4+ will not. Substituting IHttpPromiseCallbackArg<T> for R , we get the same result.

Correction

Install a file of newer types .

A relatively recent typing file would have an IHttpPromise<T> defined as

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

or

 type IHttpPromise<T> = IPromise<IHttpResponse<T>>; 
+7
source

Source: https://habr.com/ru/post/1274259/


All Articles