Areinu
Areinu

Reputation: 172

How to export typings along with a module?

I'm writing a module that adds some functionalities to testing suites our team is using. It's a project that has main typescript file, that wraps other exports from our project.

index.d.ts:

export * from "./OneModule"
export * from "./AnotherModule"

One of the modules has a functionality of adding new methods to Chai.js assertion library. This is achieved by using it's functions for adding new methods, for example:

assertion.addChainableMethod('newMethod', callback, chainCallback)

will add ability to write statements like expect(something).to.be.newMethod(). TypeScript though, doesn't recognize those new methods, since the type Assertion in @types/chai obviously doesn't have those functions.

I've created interface definition to be merged with the Chai Assertion like this:

declare namespace Chai {
    interface Assertion {
        newMethod(something: string): Assertion;
        newMethod: Assertion;
    }
}

The addChainableMethod adds new method so it can be also chaines as expect(something).to.be.newMethod.equals() that's why it has to be defined both as property and method.

The problem is, no matter how I add the above declaration to index.d.ts the new assertions aren't visible in the importing project. I suspect it's somehow wrapped in module namespace(but I might be very wrong about that). I know I can do @types/newAssertions and define them there, but that requires users to include 2 projects in package.json, and also requires our developers to handle 2 projects at once. How can I export both my Chai namespace extension and all the modules I have?

The best I've managed to do is something like that:

declare module 'my-module' {
    function AddNewAssertions(chai: any, utils: any): void;
}
declare namespace Chai {
    interface Assertion { //same as above }
}

But with this I cannot expose my other modules, and it works only when I'm only exposing AddNewAssertions function, which adds those assertions. This works perfectly though.

Upvotes: 2

Views: 856

Answers (1)

Fenton
Fenton

Reputation: 251282

I knocked up a very basic test app for this, and I had some success with adding:

declare global {
    namespace Chai {
        interface Assertion {
            newMethod(something: string): Assertion;
            newMethod: Assertion;
        }
    }
}

This makes the extension visible in your other modules, not just the one with the declaration.

Upvotes: 1

Related Questions