Ken
Ken

Reputation: 844

Managing ES6/2015 Promises in Typescript with an Angular 1 App

We have an Angular 1.5 application built with Typescript, and I am trying to figure out the best way to deal with ng.IPromise vs Promise (ES6 promise). My preference would be to only deal with the ES6 Promise type. Is there an elegant way to override all angular-js and angular-material (also included) interfaces to use es6 promises?

Options I can think of:

  1. Use some d.ts magic to do this (can it be done?)
  2. Cast to ES6 Promise everywhere (works, but not intuitive)
  3. Contribute to open source, fork the typings for ng and ng material, and make them return type of ES6 Promise (I probably should just do this, but not sure I have time for a rabbit hole right now)

Clarification

The underlying Promise implementation used by the angular application is still $q (though, I am also applying angular-bluebird-promises). I'm only trying to simplify/consolidate the Typescript interfaces involved.

Upvotes: 4

Views: 3644

Answers (2)

Estus Flask
Estus Flask

Reputation: 222493

There are very good reasons why they should remain two different interfaces.

There are fundamental differences between $q promises and other implementations. $q chain can be synchronous and runs on digest. This does not apply to other promises (namely, native Promise).

In TS/ES6 application where native and $q promises coexist, Promise and ng.IPromise interfaces can be aggregated to common denominator that fits both of them, e.g. IPromise (without ng). But it makes very little sense. Accidental use of native promise in a piece of code that expects $q promise (and vice versa) is the last thing you want to do, but it won't be prevented by Typescript if common IPromise is being used.

If the promise is expected to be exported from Angular and used by non-Angular code, it is preferable to convert it to Promise, as the other answer suggests.

For given non-Angular context

let exportedPromise = getResolvedPromise();
...
exportedPromise.then(...);

this

function getResolvedPromise() {
  return Promise.resolve($q.resolve());
};

will fire then callback on next tick. And this

function getResolvedPromise() {
  return $q.resolve();
};

will pause the chain till next root scope digest, even though then has been chained on resolved promise.

While not being relevant to TS, this question is a good example why it is important to always be aware of whether it is $q or native promise that is used.

Upvotes: 6

basarat
basarat

Reputation: 275867

Is there an elegant way to override all angular-js and angular-material (also included) interfaces to use es6 promises

We just went with IPromise everywhere. Its difficult to replace IPromise with Promise due to underlying implementation differences. You would be better off doing Promise.resolve(someIPromise) if you want to but then it wouldn't play with angular.

Upvotes: 2

Related Questions