thitemple
thitemple

Reputation: 6059

Merging TypeScript interfaces inside modules

I'm trying to merge the Matchers interface from jasmine. The interface is declare inside the jasmine namespace.

I have created .d.ts file and added the following:

declare namespace jasmine {
    interface Matchers {
        toBeSuccessful(): boolean;
    }
}

This works, but if I try to add an import statement to the .d.ts file it doesn't work. The toBeSuccessful function is not recognized.

I also tried to add this portion of the code inside my implementation of the function and not inside of the d.ts file, but then, other members of the namespace are not available anymore, for instance in this code:

class ToBeSuccessfulMatcher implements jasmine.CustomMatcher {
    compare<T>(actual: Result<T>): jasmine.CustomMatcherResult {
    }
}

The interfaces CustomMatcher and CustomMatcherResult are not available anymore.

What am I missing?

Upvotes: 4

Views: 3747

Answers (1)

artem
artem

Reputation: 51769

Adding import statement to the declaration file turns that .d.ts file into a module, and "moves" all declarations in the file into the scope of that module.

So namespace jasmine in your .d.ts file is no more in the same scope as the "real" namespace jasmine (most likely, that one is in the global scope), so your interface Matchers is also in the different scope than real Matchers, and declarations from different scopes are not merged.

The solution, when you have import or export at top level in your .d.ts file, is to use explicit global scope there:

declare global {
    namespace jasmine {
        interface Matchers {
            toBeSuccessful(): boolean;
        }
    }
}

For reference, see also "global augmentation" at the very end of declaration merging document.

Also, when you add Matchers interface inside your implementation, again it's in the different scope than the real Matchers, and it hides jasmine Matchers instead of merging with it.

Upvotes: 5

Related Questions