Skip to content

Ability for ES module to be declared as an any type either via its text or via the compiler API during resolution #51917

Closed as not planned
@dsherret

Description

@dsherret

Suggestion

With CJS, it's possible to define a module as an any type by writing:

var x: any;
export = x;

An issue is that Deno has been relying on this as a way for it to treat dependencies without types as an any type in ESM. So, the dependency has no types and Deno goes "that's fine... just use this any type, but if you want types then add a directive that specifies them". Now that we support CJS and ESM this has gotten more complicated (ex. #51321) and it would be nice to have a blessed way of doing this with esm so we can remove this code.

🔍 Search Terms

  • "any type" module

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • 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.

⭐ Suggestion

I have no idea what the text of the module could look like (declare module;?). Maybe instead this would be specified on ts.ResolvedModule or a certain kind of object returned when resolving modules to say "this is an any type". Then that module becomes represented as a non-global ambient module internally by TypeScript.

When I previously mentioned this problem on Discord, it was recommended to me that we should inject ambient modules like declare module "npm:three";. I do not believe it would be possible for us to inject ambient modules. Ambient modules have the huge downside of being global and in Deno the referrer is important for figuring out how specifiers resolve (ex. someone could use scopes in an import map to cause a specifier to mean one thing one place and then mean another thing a different place).

📃 Motivating Example

See below.

💻 Use Cases

It would be used in Deno for the runtime to mark modules as an any type so the user can use them without type checking where anything can be imported (and preferrably also re-exported) from them. We already do this, but in a non-ideal way.

Resolving this issue would close #51099 and #51136.

Thanks for considering!

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions