Reputation: 18445
Now I am sure the issue is because there is a d.ts file included which contains a module called "Shared", and a require statement which includes a variable of the same name if it is being used in a NodeJS environment.
// shared.d.ts
declare module Shared { ... }
// other_module.ts
/// <reference path="shared.d.ts"/>
if(require) { var Shared = require("shared"); }
export class Something {
public someVar = new Shared.SomethingElse("blah");
}
So when I compile other_module.ts
(which is actually a lot of separate files), it tells me Shared is a duplicate identifier, which I can understand as TS thinks Shared is a module, but then is being told it is the return of require.
The problem here is that the output of modules need to be compatible with nodeJS's require system, so in this case when other_module is required it will be in its own scope and will not know about Shared.SomethingElse
so the require is needed so the internal modules in other_module
will be able to access the Shared library, but in the browser environment it would get Shared.SomethingElse
via the global scope.
If I remove the reference then the file wont compile as it doesn't know about Shared
, if I remove the require when the module is loaded into nodejs (var otherModule = require("other_module")
) it will complain that it doesn't know about Shared
. So is there a way to solve this?
Upvotes: 2
Views: 5699
Reputation: 275799
Duplicate identifier because you have Shared
in shared.d.ts
+ in other_module.ts
.
If you want to use amd
/ commonjs
ie. external modules, you need to use import/require
(not var/require
like you are doing). Using an import
creates a new variable declaration space and therefore you are no longer polluting the global namespace Shared
from other_module.ts
. In short :
// shared.d.ts
declare module Shared {
export function SomethingElse(arg:string):any;
}
declare module 'shared'{
export = Shared;
}
And a typesafe import:
// other_module.ts
/// <reference path="shared.d.ts"/>
import Shared = require("shared");
export class Something {
public someVar = new Shared.SomethingElse("blah");
}
Inside other_module
don't use the name Shared
locally if local scope is global scope. I recommend you just use external everywhere and compile for node with commonjs
and browser with amd
as shown in fix A, but if you must here is a compile fixed other_module.ts
.
// other_module.ts
/// <reference path="shared.d.ts"/>
var fooShared: typeof Shared;
if(require) { fooShared = require("shared"); }
else { fooShared = Shared; }
export class Something {
public someVar = new fooShared.SomethingElse("blah");
}
Upvotes: 6