watzon
watzon

Reputation: 2549

Extending and renaming an import in a typescript definition file

I have a definition file for a library, jsforce, that has it's own implementation of es6 promises. The jsforce.Promise itself is just an extended version of es6-promise with a couple extra methods added. I am trying to replicate this in my jsforce.d.ts file and am hitting a road block.

Here are the relevant parts of my jsforce.d.ts:

/// <reference path="globals/es6-promise/index" />

declare module jsforce {

    interface JsforcePromise<T> extends Promise<T> {

        defer(): JsforcePromise.Deferred;

        fail(onRejected: JsforcePromise.RejectedCallback<T>): JsforcePromise<T>;

        thenCall(callback?: Callback<T>): JsforcePromise<T>;

    }

    export module JsforcePromise {

        interface PromiseCallback<T> {

        }

        interface FulfilledCallback<T, T2> {

        }

        interface RejectedCallback<T> {

        }

        interface Deferred {

        }

    }

    interface JSForce {
        ...
        Promise: JsforcePromise<any>;
        ...
    }

}

declare module "jsforce" {
    var jsforce: jsforce.JSForce;
    export = jsforce;
}

and the promise creation:

let p = new jsforce.Promise<any>((res) => {
    console.log(res);
}, (err) => {
    console.error(err);
});

Upvotes: 0

Views: 3807

Answers (1)

Pelle Jacobs
Pelle Jacobs

Reputation: 2589

I would not use the global es6-promise declaration, but use the module version instead. This gives you more control and does not pollute your global namespace. typings install --save es6-promise should do the trick.

Further, it seems like you want to extend the Promise class of es6-promise, so declaring an interface will not do the trick. Also the code example of the Promise constructor looks a bit iffy, (it seems unlikely that jsforce does not override the constructor of es6-promise, but I haven't looked into the details).

So your index.d.ts file would look something like this:

// index.d.ts
declare namespace JsforcePromise {
  interface Deferred {
    someProperty: any
  }
}

declare module "jsforce" {
  import { Promise as Es6Promise } from 'es6-promise'

  class Promise<T> extends Es6Promise<T> {
    fancyPromiseMethod(): JsforcePromise.Deferred
  }
}

Then you can use this code anywhere in your project.

// app.ts
import * as jsforce from 'jsforce'

let p = new jsforce.Promise<any>((resolve, reject) => resolve())

p.fancyPromiseMethod().someProperty

If you have any questions, let me know! And if you're writing an entire declaration of the jsforce api, you should consider submitting a PR to the typings registry so others can also benefit 😎

Upvotes: 1

Related Questions