microsoft / microsoft/TypeScript

Feature Request: Make "loaders" a first class citizen of the language

Offen
#16,170 7 Kommentare 7 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@rbuckton arbeitet bereits daran.

Seit 23.8.2019.

Needs Investigation
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

This follows some thoughts I had with "The Maybe Future of Frontend Tooling" and picks up some use cases which aren't covered by the current (awesome!) language server plugin support as far as I know. I also created https://github.com/Microsoft/TypeScript/issues/15589 which refers to linter rules. This issue is about loaders - in the sense how they were introduced by webpack.

In general both issues - this one and https://github.com/Microsoft/TypeScript/issues/15589 - remind me of Cheng Lous talks about "Taming the Meta Language" and "What's in a language?". Linters and loader are not a part of the current language in a strict sense, but part of our meta language and it is good to formalize more of them so they become a language construct. (Part of Cheng Lous talks is about why reason for example doesn't have a separate linter.)

Current state

  • Loaders like they are used by webpack allows us to require non JavaScript files (or non TypeScript files) and transform them into a JavaScript/TypeScript "file" or require JavaScript/TypeScript files and transform them so they'll have a different interface.

  • TypeScript supports loaders in two ways:

    • Either write an interface for them directly (e.g. declare module 'foo-loader?param=bar!../test';).
    • Or use a wild card (e.g. declare module 'foo-loader?*).
  • This is either cumbersome/error prone and/or limited, because they interfaces can't be typed in a very dynamic way.

  • Two use cases which we currently have, which I'd like to point out:

Use case 1

We have translations in a file called en.properties (and other files for other languages) which could look like this:

say-something={gender, select, f {She} m {He}} is great.

I'd like to import this file as import { saySomething } from '../i18n/en.properties'; which would have an interface like this:

declare module '../i18n/en.properties' {
  /**
   * `en`: {gender, select, f {She} m {He}} is great.
   * `de`: {gender, select, f {Sie} m {Er}} ist toll.
   */
  export function saySomething(data: { gender: 'f' | 'm' }): string;
}

We currently need to pre-compile our translations and emit a .d.ts and a .js, so we import the .js instead of the .proprties. Only then we get this complex interface.

Use case 2

We add new exported functions to existing modules so we can mock them easily. What will be added depends on the query parameters of the loader. It could look like this: 'import-inject-loader?fetch!../src/get-users'.

E.g. using import-inject-loader?fetch will add two new exported functions to ../src/get-users: ilOverwriteFetch and ilResetAll.

Currently we need declare every module which uses import-inject-loader as any (declare module 'import-inject-loader?*';). Everything else would be too hard to maintain.

What I'd like to see

  • I would like to get proper typings for imported files where the content changes the interface (= use case 1) without precompiling, but with importing the file directly.

  • I would like to get proper typings for files with existing interfaces, but which are transformed (in the easiest case just extended) into a different interface without loosing the original interface (= use case 2).

  • I would like to get proper typings for imported modules, when the interface changes, because of loader options (= use case 2).

  • I would like to get assistance when configuring loaders through query parameters (= use case 2, e.g. show an error, when I write 'import-inject-loader?fetch!../src/get-users', if there is no fetch used inside ../src/get-users).


If something like that isn't in the scope of a TypeScript core team, I could think of giving a new "TypeScript tooling team" this scope which develops closely together with the TypeScript core team in a similar fashion like the VS code team.

I think it is important to address these meta language issues somehow in an official way to get a nice TypeScript ecosystem.

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.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

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