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

5

18

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"
  ]
}
Fluorspar answered 8/3, 2019 at 20:36 Comment(1)
have you tried importing like import moment from "moment";? worked in my caseSuggestibility
F
49

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';
Fortnightly answered 8/3, 2019 at 21:10 Comment(1)
I started out with this import, but that didn't work when I ran it locally, so I changed it to import * as moment from 'moment', as specified by the docs. That worked locally, but gave me this same error on the build server. Why does moment behave differently locally than on a build server?Nebo
D
8

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.

Danzig answered 29/7, 2020 at 8:2 Comment(1)
Thank you so much! This fix saved me. EsModuleInterop was the villain.Pipistrelle
A
4

In my case

esModuleInterop:true

was there in tsconfig.json.

After removing this line, issue got resolved.

Anthropomorphic answered 5/11, 2020 at 10:44 Comment(0)
A
1

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
Armorial answered 8/3, 2019 at 20:53 Comment(2)
according to npmjs.com/package/@types/moment this is not necessary sinc moment provides its own types.Suggestibility
good to know that but the error is specific to type definition. @SuggestibilityArmorial
B
0

This post resolves this by changing the import from

import * as moment from 'moment';

to

import moment from 'moment';

github post

Blomquist answered 7/9, 2023 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.