How to consume the Moment.js TypeScript definition file if my site is already using moment.min.js? How to consume the Moment.js TypeScript definition file if my site is already using moment.min.js? typescript typescript

How to consume the Moment.js TypeScript definition file if my site is already using moment.min.js?


TL;DR;

Add the moment.d.ts (link) in your project from the moment github site and comment out the last line

 //export = moment;

I have created a mini test project to prove this and this works for me.

Project structure

--  |  -typings/     -moment/       -moment.d.ts   <-- //export = moment; commented out  -typescript/     -main.ts  -tsconfig.json

Contents of both typings and typescript are part of the compilation target, i.e. not excluded in tsconfig.json which looks like this

{    "compilerOptions": {        "target": "es5",        "declaration": false,        "noImplicitAny": true,        "removeComments": true,        "outDir": "dist",        "jsx": "react",        "sourceMap": true,        "experimentalDecorators": true    },    "compileOnSave": true,    "exclude": [        "node_modules",        "dist"    ]}

The main.ts file contains

const now: moment.Moment = moment.utc();

and compiles... As expected, my IDE gives me auto-completion from the definition file.(no need for ///<reference tags - you should avoid them anyway)

Removing the export statement at the end of the definition file, "transforms" it into an internal - but global - module declaration file.


One way to do this is create a custom typing, e.g. custom-typings/moment.d.ts:

export * from 'moment'export as namespace moment

And include that folder in your tsconfig.json:

{  include: [    "custom-typings"  ]}


Unfortunately, the momentjs type declarations are written in a purely modular syntax. This is because these days, many people are using npm to acquire js packages and then using module loaders such as Webpack or Browserify to bundle the npm modules in a format usable for the browser.

In your case, you are not using modules, but just relying on importing browser scripts in a global context. In order to support this, the authors of the definition files should have made the definition following UMD guidelines,which is a way to write the definition so that they support both modular and global ambient use.

Fortunately, it's extremely easy for you to add this to your copy of the definitions. Simply add the following line to the top of moment.d.ts

export as namespace moment;

What this does is basically say that when you are referencing moment.d.ts with a tripple-slash directive, it will make available everything exported from the module under a global namespace with the name of 'moment'.

This means there should now be a global moment variable accessible in the global context and you should no longer see the Cannot find the name 'moment' error.

This should be all you need to do.