Search code examples
typescriptbluebird

Problems inferring type with typescript


I have a TypeScript function which removes a "path" in a Firebase database. It return a Promise which then resolves to a boolean flag indicating whether content was actually there in the first place (aka, no need to delete if it doesn't exist).

The function looks like this:

export function remove(path: string): Promise<boolean> {
  return exists(path)
    .then(existance => {
      return existance
        ? getRef(path).remove()
          .then(() => Promise.resolve(true))
        : Promise.resolve(false);
    })
    .catch((err: any) => {
      console.log(`There was an error trying to remove the path "${path}": `, err);
      return Promise.reject(err);
    });
}

This, however, leads to the error messages below (note the difference in message is based on where in the expression i'm hovering):

enter image description here

If anyone's interested in the exists() function -- which, btw, has no problems with TypeScript -- it is:

export function exists(path: string): Promise<boolean> {
  return getRecord(path)
    .then(snap => snap.val()
      ? Promise.resolve(true)
      : Promise.resolve(false)
    )
    .catch(Promise.reject);
}

Anyway, i'm at a loss as to why I'm getting these errors and would love any insight anyone may have.

p.s. i'm using TypeScript 2.2.2


UPDATE: as has been pointed out in the comments ... these errors appear to only occur when using the popular Bluebird promise library


Solution

  • There is currently are less than intuitive ways to get Bluebird promises to override the global Promise that TypeScript provides. The issue is discussed here:

    So in short, my problems were more the impact of using Bluebird Promises in some cases but native Promises in others. To force the use of Bluebird a working solution is to:

    /src/[xxxx].js

    import * as Bluebird from './bluebird';
    

    /src/bluebird.js

    declare module 'bluebird-global' {
      import * as Bluebird from 'bluebird';
      global { export interface Promise<T> extends Bluebird<T> {} }
    }
    

    In this way you should always get Bluebird promises and the error I ran into will be avoided.


    Update ... even better solution. Include the @types/bluebird-global module and you're done!

    Note: if in your tsconfig.js file you're using the "types" parameter (most do not) then add bluebird-global to the section:

    types: [
      "bluebird-global"
    ]