1
votes

I have a Typescript declaration file that looks like the following:

/// <reference types="node" />

declare namespace foo {
    interface bar {

    }
}

declare const foo: foo.bar;
export = foo;

This compiles just fine with TS 2.0/2.2. However, if the namespace contains any class whatsoever - e.g. changing bar to a class, adding another class bam, etc. - Typescript throws an error TS2300: Duplicate identifier 'foo'., for the two declare lines. The goal of the code as written is to take advantage of Declaration Merging in Typescript, and when foo contains only interfaces, the code works as expected (types seem fine to include in foo, too). Why does declaration merging fail if foo contains any classes?

1

1 Answers

2
votes

This is because class is concrete. namespace behaves differently when it contains only types or it contains code.

When it contains code, it will also emit value. i.e. namespace x would becomes var x.

When it does not contain code, no code will be emitted.

That's why when it contains class, it will emit var foo thus conflict with your const foo.

https://www.typescriptlang.org/docs/handbook/declaration-merging.html

Here is a demo: http://www.typescriptlang.org/play/index.html#src=namespace%20foo%20%7B%0D%0A%20%20interface%20x%20%7B%20%7D%0D%0A%7D%0D%0A%0D%0Anamespace%20boo%20%7B%0D%0A%20%20class%20y%20%7B%20%7D%0D%0A%7D