How do you write a node module using typescript?

2019-01-24 05:39发布

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

2条回答
等我变得足够好
2楼-- · 2019-01-24 06:12

Typescript has really improved since this question was asked. In recent versions of Typescript, the language has become a much more strict superset of Javascript.

The right way to import/export modules is now the new ES6 Module syntax:

myLib.ts

export function myFunc() {
  return 'test'
}

package.json

{
  "name": "myLib",
  "main": "myLib.js",
  "typings": "myLib.d.ts"
}

Dependents can then import your module using the new ES6 syntax:

dependent.ts

import { myFunc } from 'myLib'

console.log(myFunc())
// => 'test'

For a full example of a node module written in Typescript, please check out this boilerplate:

https://github.com/bitjson/typescript-starter/

查看更多
Rolldiameter
3楼-- · 2019-01-24 06:15

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;
查看更多
登录 后发表回答