Caio Campos
Caio Campos

Reputation: 338

MomentJS type definition with Typescript 2.0

Alright, my first question on SO, how exciting! :)

I am trying to get MomentJS definitions to work with Typescript 2.0.

I have no issues in getting Angular definitions to work, simply by doing npm install @types/angular --save-dev.

However, MomentJS (2.15.1) already comes with moment.d.ts as part of the package you get when you install it.

If you try to do a similar approach to angular, i.e. npm install @types/moment --save-dev, this is what you get:

npm WARN deprecated @types/[email protected]: This is a stub types definition for Moment (https://github.com/moment/moment). Moment provides its own type definitions, so you don't need @types/moment installed!

And surely enough, if you go to node_modules\@types\moment, there's nothing useful in there.

Yes, I have added the tsconfig.json file on my root folder, so Typescript 2.0 will automatically pick up the @types on node_modules (this is why Angular works fine), but for MomentJS I get the error below (since the .d.ts is not on the place where TS2 expects it to be):

TS2304 Cannot find name 'moment'.

I also tried playing around with the "typeRoots" config on tsconfig.json without any luck.

This is the relevant piece of my package.json:

{
  "devDependencies": {
    "@types/angular": "^1.5.16"
  },
    "dependencies": {
        "moment": "^2.15.1"
    }
}

I am using VS2015, if this matters.

So... Any ideas on how to get Typescript 2.0 to read the type definition for Moment, that sits on an "unexpected" folder?

Upvotes: 7

Views: 5112

Answers (4)

Chris Barr
Chris Barr

Reputation: 34074

Doing the following in a customer-typings.d.ts file worked for me

///<reference path="node_modules/moment/moment.d.ts"/>
import moment = Moment;
declare const moment: Moment;

I didn't even need to make any changes to ts tsconfig.json file

Upvotes: 1

Graeme Wicksted
Graeme Wicksted

Reputation: 1815

You will find the moment.d.ts file under node_modules\moment since it is packaged with the moment itself.

With VS 2017 and TypeScript 2.2, you do not have to specify typeRoots; however, your environment may require specifying two or more of them such as:

typeRoots: [ 'node_modules/@types/', 'node_modules/moment/' ]

^ I forget if each @types subdirectory required an entry in typeRoots.

This is the process I use in VS 2017 and TypeScript 2.2 without any special changes to tsconfig.json (but this stuff changed in more recent versions):

It is automatically found via ES6 style import:

import * as moment from "moment";

This will import the functions named moment as well as the namespace moment merged into a single alias.

If you also want the Moment (return type) imported, perform the following as well:

import { Moment } from "moment";

In the current moment.d.ts (2.18.1), this type is otherwise inaccessible.

In the past I used var moment = require("moment"); but that may not be possible in your setup unless you're running browserify or requirejs to convert the CommonJS/AMD-style require to something the browser supports.

Upvotes: 4

tsu1980
tsu1980

Reputation: 2632

I had same problem. I read this comment and add declare var moment; to custom-typings.d.ts. then it worked fine, but i don't understand why.

VS2015 SP3 + TypeScript2.0.6.0, angular2-webpack-starter based project.

Upvotes: 1

rekna
rekna

Reputation: 5333

I found somewhere else (but don't remember where), that you should

change moment.d.ts by replacing export statement with

declare module 'moment' {
   export default moment;
}

add dummy file fixmoment.ts to your project with following line

import * as moment from 'moment';

Compiling with tsc directly now compiles all files. Unfortunately VS2015 still gives an error tsc : error TS2688: Build:Cannot find type definition file for 'moment'. which I don't understand.

Upvotes: 3

Related Questions