Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'IPromise<any>' is not assignable to type 'Promise<any>'

Tags:

I'm building a confirm dialog for when the user changes tabs. The code works fine but tslint complains about a type mismatch. The controller looks like:

export class MyController implements ng.IController {

    constructor(private $transitions: TransitionService,
                private $translate: angular.translate.ITranslateService) {
        'ngInject';

        $transitions.onStart({}, () =>
            this.alert
                .showConfirm(
                    this.$translate.instant('dialogs.confirmLeave.content'),
                    this.$translate.instant('dialogs.confirmLeave.title')
                )
                .then(() => true)
                .catch(() => false)
        );
    }

    ...
}

this.alert.showConfirm eventually calls this.$uibModal.open() from angular-ui-bootstrap. This gives the following warning:

error TS2345: Argument of type '() => IPromise<boolean>' is not assignable to parameter of type 'TransitionHookFn'.
  Type 'IPromise<boolean>' is not assignable to type 'boolean | void | TargetState | Promise<boolean | void | TargetState>'.
    Type 'IPromise<boolean>' is not assignable to type 'Promise<boolean | void | TargetState>'.
      Types of property 'then' are incompatible.
        Type '{ <TResult>(successCallback: (promiseValue: boolean) => TResult | IPromise<TResult>, errorCallbac...' is not assignable to type '<TResult1 = boolean | void | TargetState, TResult2 = never>(onfulfilled?: (value: boolean | void ...'.
          Type 'IPromise<any>' is not assignable to type 'Promise<any>'.
            Types of property 'then' are incompatible.
              Type '{ <TResult>(successCallback: (promiseValue: any) => TResult | IPromise<TResult>, errorCallback?: ...' is not assignable to type '<TResult1 = any, TResult2 = never>(onfulfilled?: (value: any) => TResult1 | PromiseLike<TResult1>...'.
                Type 'IPromise<any>' is not assignable to type 'Promise<any>'.

Any ideas on how to fix this?

like image 208
Andrei Roba Avatar asked Nov 10 '17 13:11

Andrei Roba


1 Answers

It looks like whatever this.alert.showConfirm() is, it isn't returning a real Promise. Try wrapping the result in a Promise:

export class MyController implements ng.IController {

    constructor(private $transitions: TransitionService,
                private $translate: angular.translate.ITranslateService) {
        'ngInject';

        $transitions.onStart({}, () =>
            Promise.resolve(
                this.alert
                    .showConfirm(
                        this.$translate.instant('einsteinsst.dialogs.confirmLeave.content'),
                        this.$translate.instant('einsteinsst.dialogs.confirmLeave.title')
                    )
            )
            .then(() => true)
            .catch(() => false)
        );
    }

    ...
}

Promise.resolve() will convert any thenable (i.e. anything that implements IPromise into a genuine Promise, but the IPromise interface isn't directly compatible with Promise.

See docs for further details.

like image 117
Duncan Avatar answered Sep 23 '22 12:09

Duncan