Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
498 views
in Technique[技术] by (71.8m points)

node.js - How do you write a node module using typescript?

So, the general answer for the other question (How do you import a module using typescript) is:

1) Create a blah.d.ts definition file.

2) Use:

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

Critically, you need both the files foo.d.ts and a foo.js somewhere in your node_modules to load; and the NAME foo must exactly match for both. Now...

The question I would like to have answered is how to you write a typescript module that you can import that way?

Lets say I have a module like this:

- xq/
- xq/defs/Q.d.ts
- xq/index.ts
- xq/base.ts
- xq/thing.ts

I want to export the module 'xq' with the classes 'Base' from base.ts, and 'Thing' from thing.ts.

If this was a node module in javascript, my index.ts would look something like:

var base = require('./base');
var thing = require('./thing');
module.exports = {
  Base: base.Base,
  Thing: thing.Thing
};

Let's try using a similar typescript file:

import base = require('./base');
export module xq {
    export var base = base.Base;
}

Invoke it:

tsc base.ts index.ts things.ts ... --sourcemap --declaration --target ES3 
                                   --module commonjs --outDir dist/xq

What happens? Well, we get our base.d.ts:

export declare class Base<T> {
  ...
}

and the thrillingly unuseful index.d.ts:

export declare module xq {
    var Base: any; // No type hinting! Great. :(
}

and completely invalid javascript that doesn't event import the module:

(function (xq) {
    xq.base = xq.base.Base;
})(exports.xq || (exports.xq = {}));
var xq = exports.xq;

I've tried a pile of variations on the theme and the only thing I can get to work is:

declare var require;
var base = require('./base');
export module xq {
    export var base = base.Base;
}

...but that obviously completely destroys the type checker.

So.

Typescript is great, but this module stuff completely sucks.

1) Is it possible to do with the built in definition generator (I'm dubious)

2) How do you do it by hand? I've seen import statements in .d.ts files, which I presume means someone has figured out how to do this; how do those work? How do you do the typescript for a module that has a declaration with an import statement in it?

(eg. I suspect the correct way to do a module declaration is:

/// <reference path="base.d.ts" />
declare module "xq" {
  import base = require('./base'); 
  module xq {
    // Some how export the symbol base.Base as Base here
  }
  export = xq;
}

...but I have no idea what the typescript to go along that would be).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For JavaScript :

var base = require('./base');
var thing = require('./thing');
module.exports = {
  Base: base.Base,
  Thing: thing.Thing
};

TypeScript :

import base = require('./base');
import thing = require('./thing');
var toExport = {
  Base: base.Base,
  Thing: thing.Thing
};
export = toExport;

Or even this typescript:

import base = require('./base');
import thing = require('./thing');
export var Base = base.Base;
export var Thing = thing.Thin;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...