Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Top-level await error message is extremely unclear #36036

Closed
DanielRosenwasser opened this issue Jan 6, 2020 · 19 comments · Fixed by #36173
Closed

Top-level await error message is extremely unclear #36036

DanielRosenwasser opened this issue Jan 6, 2020 · 19 comments · Fixed by #36173
Assignees
Labels
Domain: Error Messages The issue relates to error messaging Experience Enhancement Noncontroversial enhancements

Comments

@DanielRosenwasser
Copy link
Member

// @target: es2017
// @module: esnext

await 100;

This gives the following error message:

'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher.

This is really unclear! My compiler options are all set correctly, so why is this not working?

It's because it's not a module. This error message is expecting me to meet 3 different conditions, "top level of a module" is unclear for any user who just wants to use this feature. They'll likely take "module" to just mean "file".

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

Yeah, this is a tough one to write concisely. Do you have a better suggestion?

@DanielRosenwasser DanielRosenwasser added Domain: Error Messages The issue relates to error messaging Experience Enhancement Noncontroversial enhancements labels Jan 6, 2020
@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Jan 6, 2020

When it occurs at the top level of a file (not a regular function), regardless of compiler options:

`await` expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.

and when the options are wrong:

Top level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.

When in a regular function

'await' expressions are only allowed within async functions and at the top levels of modules.

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

Would you report both of the top two errors if both are a problem?

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

Should we have a codefix for the first one to add an export {} to the file?

Also, have we considered adding codefixes to fix the tsconfig.json for things like the 2nd error message?

@DanielRosenwasser
Copy link
Member Author

Would you report both of the top two errors if both are a problem?

Personally, I'd prefer just one at a time, but both are fine at once.

Should we have a codefix for the first one to add an export {} to the file?

Always!

Also, have we considered adding codefixes to fix the tsconfig.json for things like the 2nd error message?

I think we do, but check with @sheetalkamat

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

Personally, I'd prefer just one at a time, but both are fine at once.

I'm generally not a fan of fixing one error just to end up with another error when the fix had nothing to do with the second error. I'd rather get both so I know all the actions I need to take.

@sheetalkamat
Copy link
Member

Also, have we considered adding codefixes to fix the tsconfig.json for things like the 2nd error message?

No we haven't done that yet and there is #30739 that needs something similar...

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

Actually, it looks like we have. We have fixes already for enabling jsx (services/codefixes/fixEnableJsxFlag.ts) and experimentalDecorators (services/codefixes/fixEnableExperimentalDecorators.ts).

@rbuckton
Copy link
Member

rbuckton commented Jan 6, 2020

@DanielRosenwasser: Having a codefix to change your module to system when its currently set to commonjs seems possibly bad as those module systems are incompatible. Should we still have the quick fix, or should we only have one for module: es2015 -> module: esnext?

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Jan 6, 2020

es2015 to esnext, especially since moduleResolution can change when changing from commonjs

@rbuckton
Copy link
Member

rbuckton commented Jan 7, 2020

What do you think of these code fix names?

For 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.:

  • Add 'export {}' to make this file into a module.

For Top level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.:

  • Set the 'module' option in your configuration file to '{0}', and the 'target' option to '{1}' (if both are invalid and fixable)
  • Set the 'module' option in your configuration file to '{0}' (if module or both are invalid and fixable)
  • Set the 'target' option in your configuration file to '{0}' (if target or both are invalid and fixable).

I like being able to do both in one action, but Set the 'module' option in your configuration file to '{0}', and the 'target' option to '{1}' seems very wordy. I'm tempted to use a message like this instead:

tsconfig.json: Set 'module' to '{0}' and 'target' to '{1}'

@rbuckton
Copy link
Member

@DanielRosenwasser:

Consider the following:

// file.ts
await 1;
export {};

// tsconfig.json
{ "compilerOptions": { "target": "es5" } }

We would be able to fix the "target" as "es2017", but we can't fix the "module" (which is "commonjs" by default here). Should we even offer a codefix for "target" if we won't be able to fix "module" later?

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Jan 13, 2020

I think it's fine to say "no, we can't give a quick fix in all cases", and that might be one of them

@dilyanpalauzov
Copy link

After struggling with error error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher. for long time, I found this thread. I solved my problem by adding export {}; to my file. I do use ES6 modules, but this particular file does not need any exports.

Please adjust the error message to provide a hint, that apart from adjusting the module and target parameters, the concrete file needs an export {}; line.

@serg06
Copy link

serg06 commented Feb 24, 2022

It fixed for me when I changed "module": "ESNext" to "module": "es2022".

@Qix-
Copy link

Qix- commented Feb 27, 2022

Yeah @serg06 is right here. Why do ESNext and nodenext not work? Aggravating.

@avin-kavish
Copy link

Why do we still need to add export {} to mark it as a module, why can't it implicitly be one when type: "module" is set?

@DanielRosenwasser
Copy link
Member Author

module doesn't always imply that you don't have any globals in your program.

If that's not the behavior you want, in newer versions of TypeScript, you can configure this with the moduleDetection option and set it to force.

@jimmywarting
Copy link
Contributor

Also think having a export {} is unnecessary. should just remove that warning all together i think.
just having a top level await should assume that it's of type=module
top level await should act the same way as having export {} in the code.

More and more ppl are starting to use ESM, so your assumption that ppl use cjs or script by default is, Meh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Error Messages The issue relates to error messaging Experience Enhancement Noncontroversial enhancements
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants