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

Allow dynamic usage of import = require syntax #60884

Open
6 tasks done
kirkwaiblinger opened this issue Dec 30, 2024 · 4 comments
Open
6 tasks done

Allow dynamic usage of import = require syntax #60884

kirkwaiblinger opened this issue Dec 30, 2024 · 4 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@kirkwaiblinger
Copy link

kirkwaiblinger commented Dec 30, 2024

๐Ÿ” Search Terms

dynamic import, require, verbatimmodulesyntax

โœ… Viability Checklist

โญ Suggestion

I propose that import = require() should be allowed anywhere a require() statement is allowed (under appropriate module settings).

function foo() {
   import foo = require('./module.js');
}

๐Ÿ“ƒ Motivating Example

I've been trying to convert a commonjs project to verbatimModuleSyntax. Currently dynamic JSON imports are written as

function foo() {
   const json = await import('./foo.json');
}

which are rewritten as Promise.resolve().then(() => require('./foo.json')); by TS due to my module setting. The import() syntax currently has the advantage that TS statically analyzes and provides types for the imported JSON.

I'd like to convert the JSON import to a require() call, however, a bare require() loses static analysis. Therefore, I'd like to be able to use

function foo() {
   import json = require('./foo.json');
}

in order to have type inference and static analysis of the json file (also to have it copied to the output build).

(using a node import()-from-CJS is not available to me at this time)

๐Ÿ’ป Use Cases

  1. What do you want to use this for? dynamic require()s with static analysis, under verbatimModuleSyntax
  2. What shortcomings exist with current approaches? No static analysis of dynamic require()s.
  3. What workarounds are you using in the meantime? Not using verbatimModuleSyntax

Somewhat relates to #60598

@MartinJohns
Copy link
Contributor

Would that even be legal JavaScript syntax?

@kirkwaiblinger
Copy link
Author

kirkwaiblinger commented Dec 31, 2024

Would that even be legal JavaScript syntax?

Why wouldn't it? A require() call is always valid... It's just a function call.

@jcalz

This comment has been minimized.

@kirkwaiblinger
Copy link
Author

kirkwaiblinger commented Dec 31, 2024

Oh, I understand the question better now. This is existing TS syntax and it's required (pun intended) for CJS + verbatimModuleSyntax. I'm just asking for it to be permitted in all locations where a statement is permitted, rather than just the top level.

  • https://www.typescriptlang.org/docs/handbook/2/modules.html#es-module-syntax-with-commonjs-behavior
  • https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax
  • Proposal: deprecate importsNotUsedAsValues and preserveValueImports in favor of single flagย #51479 :

    True to its name, verbatimModuleSyntax has another consequence: ESM syntax cannot be used in files that will emit CommonJS syntax. For example:

    import { writeFile } from "fs";
    This import is legal under --module esnext, but an error in --module commonjs. (In node16 and nodenext, it depends on the file extension and/or the package.json "type" field.) If the file is determined to be a CommonJS module at emit by any of these settings, it must be written as

    import fs = require("fs");
    instead. Many users have the impression that this syntax is legacy or deprecated, but thatโ€™s not the case. It accurately reflects that the output will use a require statement, instead of obscuring the output behind layers of transformations and interop helpers. I think using this syntax is particularly valuable in .cts files under --module nodenext, because in Nodeโ€™s module system, imports and requires have markedly different semantics, and actually writing out require helps you understand when and why you canโ€™t require an ES moduleโ€”itโ€™s easier to lose track of this when your require is disguised as an ESM import in the source file.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants