prolink007
prolink007

Reputation: 34564

Cannot invoke an expression whose type lacks a call signature, using moment

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"
  ]
}

Upvotes: 19

Views: 21280

Answers (5)

dezmasterflex
dezmasterflex

Reputation: 17

This post resolves this by changing the import from

import * as moment from 'moment';

to

import moment from 'moment';

github post

Upvotes: 1

webdevius
webdevius

Reputation: 811

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';

Upvotes: 54

amar bhise
amar bhise

Reputation: 41

In my case

esModuleInterop:true

was there in tsconfig.json.

After removing this line, issue got resolved.

Upvotes: 4

Bhtyr
Bhtyr

Reputation: 81

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.

Upvotes: 8

Saikat Hajra
Saikat Hajra

Reputation: 680

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

Upvotes: 1

Related Questions