Search code examples
typescriptmomentjssystemjs

How to use momentjs in TypeScript with SystemJS?


My project's setup includes 'jspm' tool for libraries and 'tsd' tool for typings.

After installing moment's TypeScript d.ts file (these), I can't find a way to load and actually use a moment instance.

In my file (using SystemJS module loading)

/// <reference path="../../../typings/tsd.d.ts" />
import * as moment from "moment";
import * as _ from "lodash";
...
...
const now = (this.timestamp === 0) ? moment() : moment(this.timestamp);

I get a "TypeError: moment is not a function"

The definitions are structured the same as lodash, which works fine, so I don't know what might be the cause.

Can anyone help?


Solution

  • I did the following:

    I installed moment definition file as follows:

    tsd install moment --save
    

    Then I created main.ts:

    ///<reference path="typings/moment/moment.d.ts" />
    
    import moment = require("moment");
    moment(new Date());
    

    And I ran:

    $ tsc --module system --target es5 main.ts # no error 
    $ tsc --module commonjs --target es5 main.ts # no error 
    

    main.js looks like this:

    // https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/system-register.md - this is the corresponding doc
    ///<reference path="typings/moment/moment.d.ts" />
    System.register(["moment"], function(exports_1) {
        var moment;
        return {
            setters:[
                function (moment_1) {
                    // You can place `debugger;` command to debug the issue
                    // "PLACE XY"
                    moment = moment_1;
                }],
            execute: function() {
                moment(new Date());
            }
        }
    });
    

    My TypeScript version is 1.6.2.

    This is what I found out:

    Momentjs exports a function (i.e. _moment = utils_hooks__hooks and utils_hooks__hooks is a function, that's quite clear.

    If you place a breakpoint at the place I denoted as PLACE XY above, you can see that moment_1 is an object (!) and not a function. Relevant lines: 1, 2

    To conclude it, the problem has nothing to do with TypeScript. The issue is that systemjs does not preserve the information that momentjs exports a function. Systemjs simply copy properties of the exported object from a module (a function is an object in JavaScript too). I guess you should file an issue in systemjs repository to find out if they consider it to be a bug (or a feature :)).