2

I have a module "foo" that I am trying to import into 3 different files (using AMD). Here is my folder structure:

lib/
    foo.ts
views/
    view1/
        view1.ts
    view2/
        view2.ts
        sub/
            subview2.ts

I want to be able to setup foo.ts to work for None/AMD/CommonJS. If I put "export = foo;" in the file it won't compile for normal use. I want to be able to set it up as seen below:

module foo {
    declare var define: any;
    declare var module: any;

    if (typeof define === 'function' && define.amd) {
        define(() => {
            return foo;
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = foo;
    }
}

declare module 'foo' {
    export = foo;
}

The above works for node modules (because of some node magic), but it doesn't work for local files. From the folder structure I have I would need both of the following statements to work.

import foo = require('../../lib/foo');

and

import foo = require('../../../lib/foo');

TypeScript doesn't like me doing either of these, and will complain unless I use the following:

import foo = require('foo');

However this won't work during runtime (unless foo is a packaged node module, which it isn't). I understand I could go into the foo.ts file and put "export = foo;" at the root level, but I didn't write foo, and would rather not edit something I didn't write so that I can easily update it in the future.

Is there a good way around this, or am I missing something?

wjohnsto
  • 4,323
  • 2
  • 14
  • 20

1 Answers1

0

If you are using someone's JS file

local module that has conditional export

That is an implementation detail belongs in the JavaScript not in the TypeScript typedefinition (d.ts). Your foo.d.ts should look like:

module foo {
    export var SomePropertyFromFoo:string;
}

declare module 'foo' {
    export = foo;
}

The above works for node modules (because of some node magic), but it doesn't work for local files.

You can make the node magic work for you here as well. Put the corresponding foo.js file in a node_modules folder above your files and require('foo') will work at runtime. Now lets fix the compile time:

TypeScript doesn't like me doing either of these, and will complain unless I use the following

And then you can Reference+import (note : BOTH are required):

/// <reference path='../foo.d.ts'/>
import foo = require('foo');

And that is exactly what you should do for external modules.

If you own the TS file

You want the .ts file to work both with module loading and without

There isn't a supported way to do this at the moment. It's an "or" proposition at the moment (internal vs. external). The TypeScript API itself suffers from this problem (its an internal module based system and needs a hack to be exported to commonjs Get TypeScript class in a file and read single parts of it).

Community
  • 1
  • 1
basarat
  • 261,912
  • 58
  • 460
  • 511
  • In my scenario I actually have the .ts (not a .d.ts and .js). I was looking for a way to structure the .ts so that I could use it with/withought module loading. So say you have a library written in TypeScript and you want to distribute the .ts file instead of distributing a .d.ts and a .js file. You want the .ts file to work both with module loading and without. Is there any easy way to do this or do you have to do something weird? – wjohnsto Jun 18 '14 at 21:31