且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用打字稿编写节点模块?

更新时间:2022-11-09 16:35:49

对于JavaScript:

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

TypeScript:

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

甚至是这个打字稿:

  import base = require('./ base'); 
进口东西= require(’./ thing’);
export var Base = base.Base;
export var Thing = something.Thin;


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).

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;