Reputation: 11474
I'm trying to learn Typescript. While I don't think it's relevant, I'm using VSCode for this demo.
I have a package.json
that has these pieces in it:
{
"devDependencies": {
"gulp": "^3.9.1",
"jspm": "^0.16.33",
"typescript": "^1.8.10"
},
"jspm": {
"moment": "npm:moment@^2.12.0"
}
}
Then I have a Typescript class main.js
like this:
import moment from 'moment';
export class Main {
}
My gulpfile.js
looks like this:
var gulp = require('gulp');
var typescript = require('gulp-tsb');
var compilerOptions = {
"rootDir": "src/",
"sourceMap": true,
"target": "es5",
"module": "amd",
"declaration": false,
"noImplicitAny": false,
"noResolve": true,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
};
var typescriptCompiler = typescript.create(compilerOptions);
gulp.task('build', function() {
return gulp.src('/src')
.pipe(typescriptCompiler())
.pipe(gulp.dest('/dest'));
});
When I run gulp build, I get the message: "../main.ts(1,25): Cannot file module 'moment'."
If I use import moment = require('moment');
then jspm will work and bring in the module when I run the application, but I'm still receiving the build error.
I also tried:
npm install typings -g
typings install moment --ambient --save
Instead of making the problem better though, it got worse. Now I get the above error on build as well as the following: "../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."
If I go to the file provided by typings and add at the bottom of the file:
declare module "moment" { export = moment; }
I can get the second error to go away, but I still need the require statement to get moment to work in my main.ts
file and am still getting the first build error.
Do I need to create my own .d.ts
file for moment or is there just some setup piece I'm missing?
Upvotes: 120
Views: 185071
Reputation: 119
ES6 syntax:
1. install moment
npm install --save moment
2. Import "moment" in your typescript file
import moment from 'moment';
Upvotes: 5
Reputation: 11787
Still broken? Try uninstalling @types/moment
.
So, I removed @types/moment
package from the package.json
file and it worked using:
import * as moment from 'moment'
Newer versions of moment
don't require the @types/moment
package as types are already included.
Upvotes: 6
Reputation: 2993
I've just noticed that the answer that I upvoted and commented on is ambiguous. So the following is exactly what worked for me. I'm currently on Moment 2.26.0
and TS 3.8.3
:
In code:
import moment from 'moment';
In TS config:
{
"compilerOptions": {
"esModuleInterop": true,
...
}
}
I am building for both CommonJS and EMS so this config is imported into other config files.
The insight comes from this answer which relates to using Express. I figured it was worth adding here though, to help anyone who searches in relation to Moment.js, rather than something more general.
Upvotes: 9
Reputation: 741
You need to import moment() the function and Moment the class separately in TS.
I found a note in the typescript docs here.
/*~ Note that ES6 modules cannot directly export callable functions
*~ This file should be imported using the CommonJS-style:
*~ import x = require('someLibrary');
So the code to import moment js into typescript actually looks like this:
import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
aMoment: Moment,
}
...
fn() {
...
someTime.aMoment = moment(...);
...
}
Upvotes: 72
Reputation: 12032
Not sure when this changed, but with the latest version of typescript, you just need to use import moment from 'moment';
and everything else should work as normal.
Looks like moment recent fixed their import. As of at least 2.24.0
you'll want to use import * as moment from 'moment';
Upvotes: 22
Reputation: 3673
Update
Apparently, moment now provides its own type definitions (according to sivabudh at least from 2.14.1 upwards), thus you do not need typings
or @types
at all.
import * as moment from 'moment'
should load the type definitions provided with the npm package.
That said however, as said in moment/pull/3319#issuecomment-263752265 the moment team seems to have some issues in maintaining those definitions (they are still searching someone who maintains them).
You need to install moment
typings without the --ambient
flag.
Then include it using import * as moment from 'moment'
Upvotes: 151
Reputation: 32635
via typings
Moment.js now supports TypeScript in v2.14.1.
See: https://github.com/moment/moment/pull/3280
Directly
Might not be the best answer, but this is the brute force way, and it works for me.
moment.js
file and include it in your project.
$ tree
.
├── main.js
├── main.js.map
├── main.ts
└── moment.js
```
import * as moment from 'moment';
class HelloWorld {
public hello(input:string):string {
if (input === '') {
return "Hello, World!";
}
else {
return "Hello, " + input + "!";
}
}
}
let h = new HelloWorld();
console.log(moment().format('YYYY-MM-DD HH:mm:ss'));
node
to run main.js
.Upvotes: 17