How to use momentjs in TypeScript with SystemJS?

Dror Weiss picture Dror Weiss · Nov 26, 2015 · Viewed 33.8k times · Source

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?

Answer

Martin Vseticka picture Martin Vseticka · Dec 5, 2015

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