13
votes

I am trying to get moment to work in my angular application. Here is a clean sample repo to demonstrate the issue. Clone that repo and run ng build test-library in the root directory. Install packages first, npm install.

When i try to use moment, i am getting the following error. What am i doing wrong? I have been trying to fix this for a while now. I have googled it many times and tried several suggestions to no avail.

Usage:

import * as moment from 'moment';

...

  public doSomething(): string {
    const aMoment: moment.Moment = moment(); // line 22
    return aMoment.format();
  }

Error:

projects/test-library/src/lib/test-library.component.ts(22,36): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof moment' has no compatible call signatures.

tsconfig.json

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "outDir": "../../out-tsc/lib",
    "target": "es2015",
    "module": "es2015",
    "moduleResolution": "node",
    "declaration": true,
    "sourceMap": true,
    "inlineSources": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "types": [],
    "lib": [
      "dom",
      "es2018"
    ]
  },
  "angularCompilerOptions": {
    "annotateForClosureCompiler": true,
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true,
    "enableResourceInlining": true
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}
4
have you tried importing like import moment from "moment";? worked in my case - Arikael

4 Answers

35
votes

In your case, what you're importing there is everything the library exports as an object called moment. This object obviously doesn't have a call signature as pointed out by the compiler.

According to the type definitions shipped with the library, the default export is the moment function that you're looking to use.

Therefore, changing your import to the following should work:

import moment from 'moment';
4
votes

I had the same problem. And I solved the issue in two ways.

1)I set the value of esModuleInterop false under compilerOptions

"esModuleInterop": false
  1. The second way I changed the code

import * as _moment from 'moment';

to the following code

import _moment from "moment";

both options worked fine for my code.

1
votes

In my case

esModuleInterop:true

was there in tsconfig.json.

After removing this line, issue got resolved.

-1
votes

This happens when Typescript compiler does not find the type definition of the methods you are using. You need to install @types/moment as a dependency.

npm i -D @types/moment