moment: [TypeScript] "error TS2304: Cannot find name 'moment'" when used with "module":"none"
Typescript seems to not be able to resolve the global moment()
function when used in a non-module context.
tsc version: 2.1.6 moment version: 2.17.1
Repro (assuming tsc
is on your $PATH
):
$ mkdir repro && cd repro
$ npm i moment
$ echo 'const now = moment();' > test.ts
$ tsc --module none test.ts
test.ts(1,13): error TS2304: Cannot find name 'moment'.
However, using a module type works as expected:
$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js
Unfortunately, my project does not use a bundler or module system, so I’m stuck with "module": "none"
for now.
Is my only alternative to use something like typings install --save --global dt~moment
?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 21
- Comments: 53 (3 by maintainers)
+1 please fix this
I’ve resolved this using a couple of hacks that others have mentioned around a ton of issues in lots of projects that are having this problem. Just wrap it up in a custom definition file of your own. This is using Typescript 2.2. This way I’m not mucking with the dependency coming down from npmjs.org and I don’t have to check the whole thing into source control.
tsconfig.json
moment.custom.d.ts
I solved this by specifying
"moduleResolution": "node"
in my tsconfig. Not sure if this is an option for you guys, but it seems to do the trick.you have to first import in component as import * as moment from “moment”;
it worked well for me
For me it broke with 2.25.0:
I used pnpm add moment@2.24.0 as a temporary workaround.
According to #3663 the temporary fix to get it working without any bundler…
Copy
moment.d.ts
fromnode_modules/moment/
tonode_modules/@types/moment
Change
export = moment;
inmoment.d.ts
tomoment.d.ts
toindex.d.ts
Just use moment and your editor( in my case vscode ) and tsc shouldn’t complain
I’m using TS 3.0.1, is this now solved? It doesn’t work out of the box at least.
EDIT, With TS 3.0.1 I could do just this:
Hurray!
With tsconfig
"moduleResolution": "node"
did not fix it for me, unfortunatelyAdding
"module": "commonjs"
to thetsconfig.json
fixed it for meThis works for me:
// export = moment
in the official moment.d.ts filenode_modules/moment/moment.d.ts
totsconfig.json
Alternately, copy the modified
moment.d.ts
to a location of your choice and add the path to it in yourtsconfig.json
I think the main problem is that when explicitly using
"module":"none"
in tsconfig.json you can’t have any top level import or exports in any libraries (because you’re then using modules).I think that if you define
"module": "none"
typescript does not look ford.ts
files under thenode_modules/moment
folder. My experience is that it is only looking under thenode_modules/@types
folder. So there are basically these options.moment.d.ts
undernode_modules/@types/moment
/// <reference path="./node_modules/moment/moment.d.ts" />
into your.ts
filetsc --typeRoots node_modules test.ts
./node_modules/moment/moment.d.ts
intofiles
section oftsconfig.json
You also need to add
export as namespace moment;
into themoment.d.ts
file.@elSteeze
Yeah, I’m adding them to my
tsconfig.json
. Here’s a scrubbed example:Would it not help to add
export as namespace moment;
into themoment.d.ts
file?See: https://github.com/moment/moment/issues/3808
I ended up copying
moment.d.ts
into my/scripts/app
directory and implemented the fix specified in https://github.com/moment/moment/issues/3663#issuecomment-273199291Hopefully a more permanent fix will make its way into
moment.d.ts
eventually.Downgrading to 2.24.0 also worked for me. Looks like a regression in 2.25.0.
@mtgibbs Sorry for another noob like question, after implementing your solution I started getting editor errors on the moment keyword in my ts code…
'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead
I did some personal research and attempted to implement a solution by rewriting moment.custom.d.ts but unfortunately, that didn’t fix my issue.
Sorry, not trying to be one of those pesky dev’s who makes everyone else debug their code, I’m a recent grad and I’m new to working with 3rd party libraries in an Angular 2 environment
Here is my updated module.custom.d.ts
But i have to use
"module": "none"
. Commonjs is not a solution.If you do that in a file, then namespace resolution is disabled for that files.
Pls guys +1 to fix this
Still not working, the solution for me was to
yarn add -W moment@2.22.1
.When I installed the latest moment version and looked into node_modules/moment/package.json, I saw this: https://github.com/moment/moment/blob/develop/package.json#L29 - but there was no existing directory
node_modules/moment/ts3.1-typings
, so it’s not surprising TS coudln’t find it. I think there may be some bug with an installation script (or a package) or so. Yes, we have"module": "esnext"
in tsconfig.json.I’m no longer using moment for much these days, but I’m happy to re-open the issue if it’s still valid.
Yup, it’s exactly this. This is not an acceptable “fix”.
It’s only been a day and I just realized that the TS 3.0.1 workaround only imports the
moment
function, not the namespace/types. So if you want to pass a moment object into a function, this happens:Please reopen this issue, or better: fix the .d.t.s file.
It doesn’t look like Typescript 3.0.1 fix that issue, it looks like it just give us workaround.
Did anyone else also encounter the
@types/moment
npm package which is just a stub and tells you to use the file that’s provided by the normal moment package?… Why does moment have to do it differently compared to every other package? This is the reason why this issue exists, and thousands of hours were spent by developers struggling with this.
Sure, @Ciantic’s solution works in TS 3.0.1, but I don’t have to use something like
declare var moment: typeof import("moment");
for any of the other packages I’m using.Hi rossipedia, I am facing same issue in angular-6 project. As per your comments it’s resolved in TS 3.0.1 but angular6 CLI doesn’t support TypeScript version 3.0.1.
Can you please help to resolve this issue?
If I’m understanding it correctly, this will be resolved with TypeScript 2.9’s import types feature, which will allow
import
ing type definitions without affecting the the module / ambient context.@mtgibbs Hey thanks man! Appreciate the speedy reply. I’ll give that a try.