Skip to content

Allow isolatedModules with global scripts, and better match build tool capabilities #46295

Closed
@wnayes

Description

@wnayes

Suggestion

The --isolatedModules flag is typically used to ensure compatibility with build tools that don't have access to type information.

One restriction currently is that global (non-module) scripts are not allowed at all when this flag is enabled. This restriction does not match up with the capabilities of tools like the Babel @babel/plugin-transform-typescript plugin. The Babel plugin is able to process global scripts and even has impartial namespace support.

It is difficult to migrate an existing codebase to use the Babel transform plugin if it has a lot of existing global script / namespace code.

⭐ Suggestion

Minimally, it would be nice if the isolatedModules option did not raise errors for global scripts. (Enforcing "all modules" seems like it could be separate option.)

Ideally, there would be a way to configure the TypeScript compiler to do type checking that matches the capabilities of build tools like the Babel plugin.

For example, the isolatedModules option could behave as follows:

  • For module files, just behave the same.
  • For global scripts, allow them and enforce that there are no unqualified namespace references.

📃 Motivating Example

The example from the Babel documentation, modified slightly:

// FileA.ts
namespace Company {
  export const V = 1;
}

// FileB.ts
namespace Company {
  export const W = V;
}

As the Babel documentation describes, TypeScript knows to emit Company.V inside the second namespace because of its understanding of types declared globally across files, but Babel has no idea and just emits V.

It is not uncommon for existing legacy codebases to have a lot of code like this. A company could have put most of their code inside a namespace and be frequently accessing types without qualifying.

💻 Use Cases

  • Teams trying to switch to the Babel transform for emit. They may be writing new code as modules, but still have a corpus of older global script code that uses namespaces. It would be nice to not have to completely rewrite and eliminate global scripts in order to (safely) use the Babel transform and the isolatedModules option.

Alternatives

It might be possible to write something that can identify problem cases like unqualified namespace references. (A one-off script, maybe even a linter rule using type info.) That could help with getting a codebase into a state where the code emits safely through Babel. It doesn't seem that this would be convenient to use while maintaining code going forward.

🔍 Search Terms

babel transform namespaces

✅ Viability Checklist

My suggestion meets these guidelines:

  • ✅ This wouldn't be a breaking change in existing TypeScript/JavaScript code
    • It would be altering isolatedModules to raise fewer errors, so possibly a noticeable change to existing behavior.
  • ✅ This wouldn't change the runtime behavior of existing JavaScript code
  • ✅ This could be implemented without emitting different JS based on the types of the expressions
  • ✅ This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • ✅ This feature would agree with the rest of TypeScript's Design Goals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions