TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Allow disabling ambient types

Open mrmckeb opened this issue 2 years ago • 3 comments

Suggestion

I understand that this is something that there will be a range of opinions on.

What I'd like is an option to restrict ambient types so that even if a library has shipped with ambient types, they aren't exposed. Ideally, this would also prevent those libraries from modifying global types.

🔍 Search Terms

I searched for:

  • Ambient types
  • Global types

Related:

  • https://github.com/microsoft/TypeScript/issues/50424

Possibly related:

  • https://github.com/microsoft/TypeScript/issues/14306
  • https://github.com/microsoft/TypeScript/issues/17042

✅ Viability Checklist

My suggestion meets these guidelines:

  • [X] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [X] This wouldn't change the runtime behavior of existing JavaScript code
  • [X] This could be implemented without emitting different JS based on the types of the expressions
  • [X] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • [X] This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

An option in TS Config to prevent library-provided ambient types from polluting the global namespace.

📃 Motivating Example

The rationale for this:

  • They don’t feel like a good fit in modern module-based JavaScript, where globals are discouraged.
  • They create confusion - “Where is this type coming from? Is it the right type?”
  • They create inconsistency - ex. some engineers import type from React and some rely on the ambient types.
  • There is a high chance of collisions or confusingly similar names in the global space.

Further, I commented on this issue (related) and noted that we've actually encountered bugs because some of these libraries also modify global types.

  • https://github.com/microsoft/TypeScript/issues/50424#issuecomment-1233765480

💻 Use Cases

As an example, we hit an issue last year where global types were being modified by libraries, which caused type issues that were hard to diagnose and fix.

mrmckeb avatar May 04 '23 01:05 mrmckeb

Sounds like a duplicate of #50424.

MartinJohns avatar May 04 '23 06:05 MartinJohns

It's not really clear how you could make this work in a general case.

Consider the case where you have some generic type with a type constraint:

type F<T extends Foo> = ...

Let's say the library code instantiates F with a global type that you've augmented to match Foo, but which previously wouldn't have matched. Presumably, now this has to be a type error, but it shouldn't be an error because it's code that depends on an invariant that the library itself set up in the first place. That seems really awkward and also not possible for you to fix on your side.

We've looked at the problem of global pollution a lot and not yet found any solutions that don't incur these or other similar kinds of problems. See also #31894 and related discussions

RyanCavanaugh avatar May 04 '23 17:05 RyanCavanaugh

Thanks, I'm happy to close this off as a duplicate if you'd like.

I realise that this is a hard problem to solve, and I understand the issues that you've raised here.

Thinking about other rules with similar problems, exactOptionalPropertyTypes comes to mind. I've seen a lot of libraries updating code to support that option, and library authors seem very positive/receptive to those requests. If the error could prompt users to ask for/contribute a fix in these scenarios, that would help too.

mrmckeb avatar May 05 '23 02:05 mrmckeb

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

typescript-bot avatar May 07 '23 18:05 typescript-bot