0

Say I have two files:

box.ts:

export module Entities {
    export class Box  { .. Stuff }

origin.ts:

export module Entities {
    export class Origin  { .. other stuff }

As I understand javascript, those two modules should merge into one module that has both my classes in it.. (I just want them in separate files for organizational reasons, but both box and origin are entities.)

So now I have a file that needs to use both of those:

service-actions.ts:

import {Entities} from '../entities/box';
import {Entities} from '../entities/origin';

... stuff that uses both of those entities.

This gives me the error:

Duplicate identifier 'Entities';

If I have one or the other, it works fine, but both fail.

Is there a way I can combine these so that the I can do Entities.Box and Entities.Origin in my service-action.ts file?

Is the only way to do this is to put Box and Origin in the same file?

Vaccano
  • 78,325
  • 149
  • 468
  • 850

2 Answers2

1

Use as:

import {Entities as BoxEntities} from './../entities/box';
import {Entities as OriginEntities} from './../entities/origin';

// Use BoxEntities and OriginEntities here

Preferably, if you are actually exporting the classes directly from the files as you should be (and as pointed out by mk.), you could create an entities.ts file that handles it for you:

export * from './entities/box';
export * from './entities/origin';

Then import this file:

import * as Entities from './../entities';

// use Entities.Box and Entities.Origin here
David Sherret
  • 101,669
  • 28
  • 188
  • 178
1

Don't mix namespaces (internal modules) with external modules. See this post and this question and others for arguments against mixing. I've found it best to not use internal modules altogether. We don't gain any encapsulation benefits from namespaces. Instead, directories are a simple and solid way to organize code, and you are using them already.

entities/box.ts:

export class Box  { .. Stuff }

entities/origin.ts:

export class Origin  { .. other stuff }

Now instead of having to write Entities.Box, you can just import Box and use it:

import { Box } from '../entities/box';
import { Origin } from '../entities/origin';
Community
  • 1
  • 1
mk.
  • 11,360
  • 6
  • 40
  • 54
  • Good point to stress. I glanced over the part where he was using `export module` and only looked at the error. – David Sherret Dec 10 '15 at 17:16
  • I am going to have many classes like box and origin. I was hoping to combine them into a single namespace. (I tried it with internal modules and got this issue: http://stackoverflow.com/q/34207865/16241) – Vaccano Dec 10 '15 at 17:17
  • 1
    @Vaccano create an `entities.ts` file and re-export all your namespaces from there. Then you only have to import that one `entities.ts` file in your other code. – David Sherret Dec 10 '15 at 17:21
  • @Vaccano combine them into a single directory. Treat your directories as your "namespaces". So instead of `Foo.Bar.Box`, have `"../foo/bar/box"` or even `"../foo-bar/box"`. This will save you many headaches. (I'm a bit wary of re-exporting, import verbosity isn't the worst, but multiple import sources have caused problems for me.) – mk. Dec 10 '15 at 17:26
  • OK. So I got some bad advice it seems. The Typescript docs say to use internal modules (namespaces): "Applications not using node.js or require.js do not need to use external modules and can best be organized using the internal module concept outlined above." (Taken from: http://typescript.codeplex.com/wikipage?title=Modules%20in%20TypeScript&referringTitle=TypeScript%20Documentation) – Vaccano Dec 10 '15 at 17:27
  • Seems like external modules are best, but that where possible I should let the file be the implicit external module. Does that sound right? – Vaccano Dec 10 '15 at 17:28
  • 1
    @Vaccano Yes that sounds right. If you write `export class Foo` in your file, it will be an external module. (Also, you'll eventually run into posts that push for `export default` - take them with a grain of salt. That syntax is nice for all those old-style js modules like `$`, but it actually forces an alias even for classes, which means class names don't get updated across default imports when you refactor.) – mk. Dec 10 '15 at 17:36
  • @DavidSherret - thank you both for the help! This would have taken HOURS of trial and error to figure out on my own. – Vaccano Dec 10 '15 at 17:44