question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:7
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
raixcommented, Jan 12, 2019

It might also be related to https://github.com/Microsoft/TypeScript/issues/3136

We currently preprocess language files creating a typescript file with comments containing english translation - we parse the ICU format providing types for the translation functions/react components giving us full typings. (code documentation is also important for us)

Working on the translations we have to rerun the translation generator when editing and we cannot look at the json files to see parsing errors or code references.

The typescript loader could provide:

  • ast
  • typings
  • code documentation
  • source map
  • compile errors
1reaction
donaldpipowitchcommented, Jun 9, 2017

I thought TypeScript language plugins allow extending the type checker as well as module resolution so I decided to write a TypeScript plugin for typed-css-modules but it’s not possible with current plugin architecture.

Yeah, currently it is not possible. Taken from RyanCavanaugh/sample-ts-plugin:

Examples of things language plugins cannot do:

  • Customize the type system to change what is or isn’t an error when running tsc
Read more comments on GitHub >

github_iconTop Results From Across the Web

When is a feature considered a "First class citizen" in a ...
I would say a feature is a first class citizen if it is implemented solely by the language. i.e. it ...
Read more >
Importing modules with loaders extension #10988 - GitHub
I've made a webpack loader for implementing language packs. While build it creates language packs (bundles) for each produced built chunk, each ...
Read more >
First-class citizen - Wikipedia
In programming language design, a first-class citizen in a given programming language is an entity which supports all the operations generally available to ......
Read more >
Who Is First-Class Citizen In Programming World? - Medium
A programming language is said to have first-class functions when functions in that language are treated like any other variable. For example, a...
Read more >
Ability to create multi-line formulas on the fly - Feature Request - 4D ...
Hi,. We now have wonderful tools that can use formulas. These formulas are very useful as they can also be properties or parameters....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found