microsoft / microsoft/TypeScript

Add compiler option to allow module types to be checked in non module output files

Offen
#41,567 26 Kommentare 27 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

In Discussion Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

Search Terms: import type, export {}

Suggestion

In #41513 and #41562 projects are broken by a design change to always include export {}; in the JS output if import or import type is in the TS source, regardless of whether it is in the JS output. This is a breaking change for a lot of developers and painful to fix (and by fix I mean practically get the output of our TS project to run in browsers, not necessarily adhere to ECMA spec compliance and best possible practice).

However, export {}; considered desirable:

You're free to suggest a new compiler option but this is the intentional behavior.
Originally posted by @RyanCavanaugh in https://github.com/microsoft/TypeScript/issues/41513#issuecomment-727057724

Please could we have a new compiler option to not force all files that in any way use ES modules to always have to include export {}; in the JS output.

I'm not sure of the best way for this to be applied, but the goal would be

  • Type checking compatible with an ESM project.
  • Output compatible with the current state of module support in browsers.

This could be:

  • A compiler option that causes import type to not implicitly convert output to a module, (my preference because it still avoids any output JS having import without export, which caused #38696) or
  • A compiler option to not add export {}; to all modules, or
  • A //@directive we add to a file to express our intent to not output a module, or
  • A new reference type ... TS-only syntax to signal that we want to use the definition but not output a module

Whatever is easiest to code and causes least friction/confusion for the community.

Use Cases

I have a large TS project that uses numerous web workers, a service worker and web components that load side effects.

In the first two cases including export {}; breaks the resulting JS, as these workers are not modules and are not intended to produce module loaded JS output.

In the case of side effect web components no export is expected (they use customElements.define) so it's just wasted bytes, but it doesn't break anything. Across a project with a lot of components the many export {}; that will never be referenced by anything adds up.

In addition during migration between different reference types it may be extremely beneficial to not strictly enforce adherence to one type or the other, at least while not in production. Any modules = all must be modules effectively makes this migration harder, even if it is a sound best practice.

Examples

I have a model MyModel.d.ts.

In worker.ts I want TS to check my code against this model:

import type MyModel from './MyModel';
const test: MyModel = {};
test.propertyInModel = 1; // works and has intellisense
// test.propertyNotInModel = 1; throws compile error!

I want to use the JS output this with a worker in another file:

const worker = new Worker('path/worker.js');

This worked in 3.8, but fails in 4.0 due to #41562

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code (it would fix a lot of projects broken by 4.0)
  • This wouldn't change the runtime behaviour of existing JavaScript code (it would be opt-in)
  • 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, etc.) (we're removing additional content that wasn't in 3.8)
  • This feature would agree with the rest of TypeScript's Design Goals. (particularly 4, 7 and 11)

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Es werden keine Implementierungsdateien oder Tests genannt. Beginne damit, die verwandten Issues #41513 und #41562 sowie die Diskussion hier zu lesen, und verfolge anschließend, wie import type und export {} die Modulklassifizierung und das ausgegebene JavaScript beeinflussen. Als abgeschlossen gilt die Arbeit, wenn ein klar definiertes Opt-in-Verhalten vorhanden ist, das ESM-kompatible Typprüfung beibehält und zugleich eine Ausgabe ohne Module ermöglicht, mit Abdeckung für die beschriebenen Fälle von Worker und Web Component.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.