TypeScript: "Cannot compile namespaces" error with --isolatedModules and no namespaces
TypeScript Version: nightly (2.3.0-dev.20170417)
Code
function f() {}
Expected behavior:
No error, or an error message about a non-module file in an --isolatedModules project.
Actual behavior:
src/a.ts(1,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided.
This occurs because we in program.ts verifyCompilerOptions to look for any source file that isn’t an external module declaration, and fail on the first one, whatever it may be.
The error message should be upgraded to reflect the real reason we issue this error, and not mention namespaces.
Alternately, we could just allow files without imports and actually look for a namespace before adding this error.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 30
- Comments: 54 (4 by maintainers)
Commits related to this issue
- Fix issue #15230 — committed to hami9x/TypeScript by hami9x 7 years ago
A global file cannot be compiled using '--isolatedModules'. Ensure your file contains imports, exports, or an 'export {}' statement.ATTENTION - If you are using a create-react-app and you see this issue like I am… I was able to bypass this by making a change to my tsconfig.json file…
Changing the following
to
Just add
I wound up here while trying to fix a sort-of-related annoyance. Comments below are just to help any other VS Code users searching about this error with create-react-app and TypeScript.
When configuring a proxy with create-react-app 2.x and TypeScript, you add a file named
setupProxy.jswith code like this:react-scriptsreads this file outside of the ts transpilation process, so it must be plain js.This works exactly as documented, but it has an annoying side effect.
The
tsconfig.jsongenerated byreact-scriptsincludes all files insrc, includingsetupProxy.js. As a result, it triggers VS Code to show theCannot compile namespaces...error insetupProxy.js, mark the code with a red squiggle and include it in the Problems pane. In my setup, it also highlights the file and all its ancestor folders in red.Solution: Suppress the VS Code error message by excluding the
setupProxy.jsfile in tsconfig.json.react-scriptsforcesisolatedModules: true, but it doesn’t appear to overwriteexclude.Alternative: Add a named export to `setupProxy.js:
With a top-level export, it’s now valid with --isolatedModules.
I often find myself doing this in small tests.
I really want an option that causes TypeScript to consider every .ts file as an ES6 module, regardless of whether it contains import/export statements or not. I originally assumed the
--isolatedModulesoption was that option, but it causes this extremely confusing error on import/export-less files. (I still don’t understand what the error message means by namespaces. I don’t think I’m using that feature.) The reason I want this setting is because I’ve had several issues go uncaught by TypeScript because I accidentally referenced a top-level variable from one .ts file in another (which both didn’t have import/export statements, so TypeScript didn’t treat them as ES6 modules) despite using node/parcel/webpack where files can’t reference each other’s unexported variables like that.@jamespfarrell Put
export {};somewhere in your file.Maybe somebody else will have the same issue: I had the same error appearing for a few files I’ve left as placeholders with no content in them but I’ve been importing them in other files, ie. I had empty styles.js file which was imported in another component file.
Here’s a minimal repro case, using typescript@next (full repo at https://github.com/yang/sandbox-ts-namespaces-error):
src/a.js: (notice, no import/export keywords needed)
tsconfig.js:
Error:
I too first encountered this via
create-react-app --typescript, which instructs you to create a setupProxy.js (or setupTests.js). CRA also setsisolatedModulesandallowJsto true. It seems to have not been an issue until a more recent typescript version (I didn’t see errors about setupProxy.js while on typescript 3.1.x, only after updating to 3.2.x or 3.3.x).The workaround of adding .js files to your exclude set works when running tsc, but - annoyingly - you still see errors from those files in editors from the TS language service (tried both VS Code and Webstorm). (This seems to be a separate and more general issue with the TS language service not respecting excludes - but I wasn’t able to find an existing issue for that.) To mask this error in the editors, I added .d.ts files for the *.js files.
Furthermore, require-ing or import-ing the .js files renders the exclude ineffective as well, causing the error to be raised (outside your editor).
Only disabling allowJs (against what create-react-app suggests) seems to be working for me.
No idea why i’m getting this error on that specific file. Other files behave fine
Yes, that will work around the issue. (Assuming you’re not actually using TypeScript
namespace. Otherwise you have a different and probably legitimate issue.)Just figured it out if anyone else is having the same issue. Simply add your declaration types to the
react-app-env.d.tsfile in the source folder when using create react app.So I had this error because I had a
.jsfile in the root folder of my project, in my tsconfig.json file I had this configured:I had to switch it for this:
That fixed it, but I don’t understand why, can someone explain it to me? My understanding was that including
srcwould eliminate root files and sibling folders.So the solution should be: detect real namespace usage before throwing out this error message (i.e the “alternative” solution that @andy-ms proposed). We can’t just change the text to something else because an error message in this case is totally wrong. I want to make a PR, but can I still be trusted here after spewing out all those bullshit?
I had this error for a module definition that I accidentally suffixed
.tsinstead of.d.ts, if anyone else is making that particular mistake. Have to restart server after fixing.Those errors you’re getting now are unrelated to the isolatedModules setting. If you turned off isolatedModules, you’ll still get those errors.
Where is this error happening? It sounds like you’re trying to import the default export of a file that doesn’t have one, like
import Foo from './workers/HeartBeat.worker.js';. If you don’t want to import a default export, then change your import line toimport './workers/HeartBeat.worker.js';.@Macil thanks for your advice.
I get this error:
If I add:
export default {};I get:
@Bnaya at a guess, the files that work are using import or export statements? Only use one of
require()/module.exportsandimport/exportin your code. Otherwise, check that all your files are covered by the tsconfig include (check the docs for full detail on that@TomasHubelbauer Module declarations should be in a .d.ts for this reason, amongst others. I only had CRA re-add settings I removed, not change them back, but perhaps it’s more insistent for isolatedModules?
I am in a situation where I am using CRA TypeScript and importing a package which has no
@types. I want to add adeclare module 'package'to provide my own types, but I cannot put this statement in any module file. So I go ahead and createtypes.tsto place thedeclare modulestatement there. Now I get this error.When I override
isolatedModulestofalse, CRA changes it right back for me. That’s not a solution.When I add
export {}to thetypes.tsfile withdeclare module, I get Invalid module name in augmentation. instead. This error is avoided by putting the declaration in a non-module file, but CRA through this forcedisolatedModulessetting forces every file to be a module!So there is a circular path of solving one error only to land on another and back. How can this be resolved?
Just ran into this message due to a file an “empty” file (i.e. the whole file was commented out). I’m happy TS caught this, but the error message was extremely opaque (and the colors were broken on a vanilla CentOS 7 Install, but this probably due to the webpack dev server, not related to TS directly)
Yes, it will.
The point of the
--isolatedModulesflag is to validate that a program can be successfully compiled through single-file transpilation.The TypeScript codebase can’t be successfully compiled through single-file transpilation. There is code like this everywhere:
file1
file2
If we single-file transpiled file2, it would break.
@mhegazy Yes and that rule is exactly the root of the problem we have here. The rule unfairly treats a file without import or export as a part of the legacy internal module system, so
--isolatedModulesrejects the file.Now we should not change the rule because that will probably break a lot of things, but we can solve the current issue very easily just by removing this error message.
Let’s imagine this “cannot compile namespaces” error message being removed, what could go wrong? What about a codebase that uses internal module, like the Typescript compiler itself? With
--isolatedModuleson, would it compile to garbage code and confuse the user? No it won’t, there would be a lot of Typescript error messages about undefined symbols, because--isolatedModulesbroke the links between the files, pretty obvious to understand. Can you find ANY downsides with removing this error message? I couldn’t. Why wouldn’t we choose the easiest solution, that involves zero work (just remove the lines) and has no downsides?@andy-ms I was trying to point out that the whole code to check for this error is just pointless, and we should just remove it instead of complicating the code more. My point is, when
--isolatedModulesis on, every file should be regarded as an external (ES6) module, period. In that sense, usage of Namespaces should be legal because right now, it is perfectly legal to use Namespaces inside ES6 modules (with--isolatedModuleson).In #15839 I intended to modify the checking behavior but later realized that this check is just pointless and the ideal solution is to remove it. Typescript has always allowed usage of namespace inside an external module with
--isolatedModuleson:Thus the check isn’t doing anything in that (seemingly invalid) case, when it’s supposed to complain. So why complain when the programmer isn’t even using any namespace, doing nothing wrong?
There should not be an error message in this situation. The --isolatedModules option should just turn off the internal module system completely, if tsc still errors out this way then the option didn’t do its job.