2
votes

My questions are around working with commonJS (node style) and ES6 modules (using typescript). I have this angular 1.5 app which uses the commonJS module system. I attempted to use typescript for creating just one of the factories in the app. Few questions on the same.

  1. Can we use typescript import keyword to import a module exported using the commonJS module.exports syntax? For example, say we have RandomService.js below that we wish to use in our typescript file. I noticed that doing an import * as randomservice from '../../services/RandomService.js' threw some errors related to not being able to find the module. I got this to work by using a require(), but just wanted to know if this can be done in typescript?

    var randomString = require('random-string');
    module.exports = {
        getSuperRandom: function() {
            var x = 'super-random-' + randomString();
            return x;
        }
    }
    
  2. When we export a module from a typescript file usually the exports object has a property which holds our object. Even doing an export default results in the .default property having our exported object. Is there anyway where we can set the exported object directly to the exports object (just like we can do in commonJS module system where we do module.exports = 'helloservice')?

1

1 Answers

2
votes
  1. Yes it's possible to import commonJS modules written in javascript, but only if typescript compiler can find declarations for these modules.

For example, if you have this javascript module in module1.js:

exports.f = function(s) {
    return s.length
}

you have to provide declaration file that describes the module and defines types for its exports, in file module1.d.ts:

export declare function f(s: string): number;

Then you can use this module with import. Typescript will find imported module if you put this code in test.ts file in the same directory as module1.d.ts:

import * as module1 from './module1';

let n: number = module1.f('z');

If you compile this code with --module=commonjs (which is the default), you will get pretty normal commonjs code as a result:

"use strict";
var module1 = require('./module1');
var n = module1.f('z');
  1. If your module exports some object, for example like this module2.js:

     module.exports = {
         a: 'a',
         n: 1
     };
    

it's better to avoid importing it using es6 syntax - es6 always assumes that module exports a namespace, not an object. In typescript, there is special syntax called import require for that:

import m2 = require('./module2');

let n1: string = m2.a;

the declaration file, module2.d.ts, must use export assignment syntax:

export = {} as {a: string, n: number};

The actual value, {}, does not matter in the declaration file and can be anything - only the type matters (which is given as type cast to unnamed interface).

If a module exports a string, as in your example, the declaration can be as simple as

export = '';