microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.29k stars 12.39k forks source link

Offer option to resolve module path maps in emitted code #26722

Closed dannycochran closed 4 years ago

dannycochran commented 6 years ago

Search Terms

paths tsconfig.json compilerOptions ts-node node cannot find module

Suggestion

Per #10866, module path maps are not resolved in emitted code. This means that if you attempt to run the emitted code with node, it will be unable to resolve those paths and the server will not start.

Current solutions:

  1. use browserify or webpack to bundle the output -- this is an unfortunate solution given that it'd be the only reason for me to bring in one of these tools, as I've managed to build and deploy apps using just the typescript compiler. This blog post from the TypeScript team even strongly recommends using a TypeScript toolchain:

https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/

For that reason, we feel tsc and the tools around the compiler pipeline will still give the most integrated and consistent experience for most projects.

  1. use a tool like module-alias. This is a bit gross as it requires duplicating the path maps, and inserting code at the root of your server.

Proposed solution:

Offer a compilerOption, something like resolvePaths, that resolves aliased paths to their relative paths.

Use Cases

So that I can continue to meaningfully use the paths property in tsconfig.json.

Examples

Please see the example in #10866.

Checklist

My suggestion meets these guidelines:

DanielRosenwasser commented 6 years ago

I think you want #16577.

DanielRosenwasser commented 6 years ago

Just to elaborate a bit here, we haven't moved on that issue given that there are so many moving parts in the modules space that anything we do would be irrelevant or deprecated in 2 years.

For ts-node, can you use tsconfig-paths, as per this documentation?

dannycochran commented 6 years ago

Hey Daniel, thanks for the quick response.

I don't think this is a duplicate of #16577 -- this issue deals with aliases not being resolved to their relative paths on build. I should have been clearer in the description rather than linking to an old bug.

E.g, given this directory structure:

tsconfig.json
common
  - helper.ts
server
  - index.ts

Where tsconfig.json maps common to @common, like this:

compilerOptions: {
  ...
  "paths": {
    "@common/*": [
      "./common/*"
    ]
  }
}

And this code in server/index.ts:

# server/index.ts
import { foo } from '@common/helper';

When TSC outputs this, it keeps the alias rather than resolve it to the relative path. And node doesn't know how to resolve this.

Unfortunately, I don't think you can use tsconfig-paths when running node against JavaScript files. I use tsconfig-paths to run my server in development, e.g;

node -r ts-node/register -r tsconfig-paths server/index.ts

But this does not work:

node -r tsconfig-paths server-build/index.js

My request is that the TypeScript compiler offer an option to resolve the aliases to relative paths so that node can properly run the outputted code. Otherwise, the "paths" feature in tsconfig.json is somewhat unhelpful, as it requires bringing in additional tools to reconcile the output.

deejayy commented 6 years ago

Check out this gist: https://gist.github.com/deejayy/aa5f0cde76dc29f6b4127e60e74be2f2 It resolves the paths from tsconfig.json. Dirty hack, but works.

icopp commented 6 years ago

A simple use case that tsconfig-paths doesn't really help with:

Right now, the only way to do this is to have a Babel compile step happen with @companyName/some-shared-frontend-stuff, which complicates dev work pretty painfully because I can't just use tsc -b --watch with npm link and instead I have to have a separate file watcher that re-does Babel builds when things change.

dannycochran commented 6 years ago

@DanielRosenwasser provided my previous comment makes sense, can we remove the duplicate flag or discuss further?

dannycochran commented 5 years ago

@DanielRosenwasser pinging again. Any chance this could go on the roadmap for 3.2?

joonhocho commented 5 years ago

Until officially supported, I've created a solution that does not require any dependencies nor babel. It also fixes .d.ts files (currently only if they are in the same directory as output. declarationDir support can be added too. PRs are welcomed!). https://github.com/joonhocho/tscpaths

dannycochran commented 5 years ago

@joonhocho there are existing third party solutions, the idea is to avoid them entirely.

@DanielRosenwasser pinging again -- this is still marked as a duplicate and it shouldn't be. can we re-evaluate?

alexandertrefz commented 5 years ago

@DanielRosenwasser please reevaluate this issue. The proposed solution is simple, and has nothing to do with the reasons you mentioned for rejection - this doesn’t align with any 3rd party tool, it just makes the TS internal paths option work like the vast majority of people expect. Please consider this.

Every week an issue is opened about this, and quite a few have very long and very strong comment sections that all echo the same 2 things:

1) This is incredibly unintuitive which wastes a ton of time and turns users away from the language because they get a "successful" compile that yields code that can't be run

2) The only thing people want is a simple string replace at compile time that turns the paths path back into normal paths. That this is achievable is shown by tools like rollup - which is doing JUST THAT, without any confusion or problems - it just works. Like it should out of the box in tsc

dannycochran commented 5 years ago

@andy-ms could I get your eyes on this issue? I think Daniel errantly resolved this as a duplicate a while ago, but per my explanation above (https://github.com/Microsoft/TypeScript/issues/26722#issuecomment-417020795), it's not.

I think given the reactions to this FR and the original issue (#10866), it would be a well received addition to TS.

ghost commented 5 years ago

I think it's unlikely that we would change the module specifier you wrote when emitting -- #16577 is an existing issue that asks for that kind of functionality, and if we ever did add that then maybe we would take a look at this too.

dannycochran commented 5 years ago

@andy-ms ah my mistake I read through the issue more and understand how this is a dupe. Thanks for taking a look.

eyedean commented 5 years ago

It's so different from 16577, and more important!

While this issue and https://github.com/microsoft/TypeScript/issues/16577 look similar in terms of "customizing emitted code on module paths", I think there is a subtle difference between the two and I'd like to ask for reopening this issue as its own.

Let's say I have the following import in my typescript code

import helper from "@utils/helper";`

and in tsconfig.json I have set:

"paths":  {
   "@utils/*": [ "src/interal/tools/utils/*" ],
}

The problem with this one is, there is an actual piece of information, (rather than just a .js extension like https://github.com/microsoft/TypeScript/issues/16577), that is getting lost. It's because tsc just emits the same path as following:

const helper_1 = __importDefault(require("@utils/helper"))

and the piece of information that @util is actually pointing out to somewhere specific in my codebase (i.e. src/internal/tools/utils) is swallowed by the compiler! Unlike the .js extension issue, there is no way on earth that one can infere this mapping and fix this code, only by looking at the output of the compiler.


Exesting Third Party Solutions

To solve this issue, I need to either re-enter the same mapping manually for the consumption of my JS Loader via something like module-alias (funny, I'm already doing it once for ESLint!) which requires having multiple entries in the codebase for the same concept, a terrible practice; or I should use a tool like tsconfig-paths that reads tsconfig.json and does what compiler is failing to do!

It's interesting to me that for this very problem, tsconfig-paths has got to 500K downloads/week! In the mean time, all the tickets asking for this simple functionality have been closed here: https://github.com/Microsoft/TypeScript/issues/16640, https://github.com/microsoft/TypeScript/issues/18951, https://github.com/microsoft/TypeScript/issues/18972, https://github.com/microsoft/TypeScript/issues/19453, and so on! (PS. Just found https://github.com/Microsoft/TypeScript/issues/10866 from years ago with tons of emojis!)


Proposal

It's really simple.

tsconfig.json already has 89 flags. Let's add the 90th one as --resolveMappedPaths (or something similar) which, at the time of compile, will replace any mapped path (coming from the "key" side of the property in the paths object) to its destination ("value" side of the same property!)

So my tsconfig.json would be:

   "compilerOptions": {
      "module": "commonjs",
      "esModuleInterop": true,
      "target": "es6",
      "noImplicitAny": true,
      "moduleResolution": "node",
      resolveMappedPaths: "true"
      "..."

It can also be a property on an overloaded per-path-basis config, e.g.:

"paths":  {
   "@utils/*": { 
       "resolveOnCompile": true,
       "target": [ "src/interal/tools/utils/*" ]
   },
}
nuno-tomas commented 5 years ago

+1

yang4515 commented 5 years ago

+10086

joseluisq commented 5 years ago

For production apps after a tsc build. I have created a TS Paths replacer in Go which is pretty fast and that addresses the custom paths issue. After it's applied you only need to run your app node main.js.

MikeMitterer commented 5 years ago

@joseluisq Thanks! But @DanielRosenwasser I don't get it why we don't get a compiler flag to resolve the path. Just to make the path-feature work we have to usw webpack or another bundler. It does not work with tsc. You say "it's our main goal not to change the generated JS code" but path-maps with tsc breaks the code!!!! I have two options - Use webpack for this problem to solve or stay with those ugly, long, import path statements...

DanielRosenwasser commented 5 years ago

You say "it's our main goal not to change the generated JS code" but path-maps with tsc breaks the code!!!!

Path mappings are meant to reflect the behavior of whatever is actually resolving .js files. The idea is not to break your code, but to reflect the behavior of something like webpack's resolve.alias or AMD's paths field.

I don't get it why we don't get a compiler flag

Because a compiler flag doesn't actually relieve us of the burden of the complexity of a feature - it just makes it harder for us to think about.

MikeMitterer commented 5 years ago

@DanielRosenwasser Thanks for your answer!

the burden of the complexity of a feature For this particular case??? Seems not sooo complex to me.

My main problem is that I really like what tsc gives me - multiple output files! Every TS-file produces a JS counterpart. That's cool. Readable, understandable and nice. That's what I use for all of my libs. I use webpack for the main application - OK.

is not to break your code But this is what tsc produces without the help of WebPack - shouldn't tsc produce valid AND runnable code just out of the box???

I can choose between two options.

[Update] Hmmm. I found this plugin for ttypescript - it seems to work but I still think this should be part of the official tsc-compiler. If you don't want to support the mentioned compiler flag, another way to open TS/tsc would be a better support for transformers e.g. like ttypescript . I understand that you want to be as close as possible to JS but on the other hand at least a bit more flexibility would really help

icopp commented 5 years ago

but to reflect the behavior of something like webpack's resolve.alias

But when you use that in webpack, the resulting build actually works. When you use path mapping in TS and use the TS compiler, the resulting build doesn't work.

wintercounter commented 5 years ago

+1 for this, same issue here. We're using TSC only for type-check and generating d.ts files. The rest is Babel. In Babel we're resolving our aliases fine, but the generated d.ts files will still have the alieses in the copiled code. I also don't understand why this issue have to be closed.

regniblod commented 5 years ago

+1

belaarany commented 5 years ago

+1.....

MikeMitterer commented 5 years ago

@wintercounter >I also don't understand why this issue have to be closed. Nobody does! Is this really OpenSource???? Microsoft blocks this feature in a very dictatorial manner

elmcrest commented 5 years ago

Also wondering - this is really making a theoretically nice feature (having nice imports) completely useless. I mean I don't have any Idea how hard this is to implement but from a naive though it's just s/@alias/realPathFromTSConfig ... no?

kitsonk commented 5 years ago

Some people need to learn to read.

The issue is closed because it is a duplicate. The original author indicated that they understood it as such. When the original author agrees it is a duplicate, it is a duplicate, no matter what you think and #16577 is still open people!

wintercounter commented 5 years ago

I agree with your first statement (so please go through the comments). Most of the people doesn't consider this as a duplicate and neither do I. The mentioned issue is a whole different topic and that's the main reason this thread could grow as huge as now.

kitsonk commented 5 years ago

If it is a different issue than the OP, who agreed it was a duplicate then open a new issue that isn't a duplicate that better describes the problem/proposal because it is a different issue...

wintercounter commented 5 years ago

I went through all the comments of that issue and find no relevance to our problem.

On Thu, Aug 22, 2019, 00:16 Kitson Kelly notifications@github.com wrote:

If it is a different issue than the OP, who agreed it was a duplicate then open a new issue that isn't a duplicate that better describes the problem/proposal because it is a different issue...

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/microsoft/TypeScript/issues/26722?email_source=notifications&email_token=AAHLJQAEHCFEIKQO3LPESCTQFW5DVA5CNFSM4FSCEI7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD43JE5Q#issuecomment-523670134, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLJQEAQ6AP75R544A4HBTQFW5DVANCNFSM4FSCEI7A .

MikeMitterer commented 5 years ago

@kitsonk Are you sure you red correctly? @dannycochran nailed it ONE!!!! year ago: https://github.com/microsoft/TypeScript/issues/26722#issuecomment-417020795 What should we do to get this feature - start a petition?? It can't be so hard to solve this problem.

In my opinion it's a philosophical, MS internal, debate that holds back this feature (BTW we shouldn't call it feature - it solves ab bug. Using only tsc to generate code, breaks the app/lib if you use path mappings)

However, (imagine me on my knees), PLEASE add this feature (solve this bug)!

joseluisq commented 5 years ago

I can understand the team concerns if they have technical reasons to don't implement the feature.

But if TS provides path aliases at development time why those are not also supported in building process via tsc? Why I need a third-party dependency for a TS feature?

eyedean commented 5 years ago

It's been two months since I posted a proposal above.

The situation we are in is like going to McDonald's and asking for a burger without a bun. Then, in a big surprise, you hear "we are not going to cook that thing" and "oh, it's similar to the request of other customers who wanted a veggie burger with yellow bell pepper and avocado." Unfortunately, none of them are accurate, and I can unblock myself by buying a burger and tossing away the buns manually. But, due to the extra overhead and the shocking way I am treated, I'll probably reconsider visiting there again in the future.

Same is here. People in the Open Source Community totally understand if a request has less priority than other works. However, keeping a clear request with an accurate proposal "closed as duplicate" and not caring at all can hurt. It hurts the emotions of the current customers of the platform (developers) at first, but then such demoralization will eventually lead them to shop elsewhere in future. That's when it might ultimately hurt back the community/project/team.

At the end of the day, what makes a project alive is just how users of the project feel they are treated. There are tons and tons of dead projects and dead packages that people stopped using because no one hears them (just hear them and acknowledge them) when they have a legit request. And it's totally rational -- as an architect or senior software engineer in charge of a big project you don't want to invest 6 months on something in future and then when you face a problem that hunderds of others are facing too, you see the community has closed the door with "WE DON'T CARE" sign, instead of "Oh, we hear you. That's right. Let's democrazie it and post a 'Help Wanted' sign on this to see who will volunteer. :)"


To recap:

Is what we want a duplicate of the issue that marked as duplicate?

Absolutely NOT.

They can fall into the same category of "custom module specifier", just the way you can put chicken and burger in the category of "food". :)

In fact, it was @andy-ms who mentioned that internally they are thinking about a dependency of implementation:

I think it's unlikely that we would change the module specifier you wrote when emitting -- #16577 is an existing issue that asks for that kind of functionality, and if we ever did add that then maybe we would take a look at this too.

It's like saying when we start serving chicken with lettuce then we will serve burger with no bun. Sure, it's your call internally how you want to build dependencies. But it doesn't mean I should now sit and wait for chicken with lettuce!

Is this a breaking feature?

Absolutely NOT.

We are asking for a new flag next to the existing 89 ones.

Is this a random irrelevant just-fancy feature?

Absolutely NOT.

There is no way that you can natively use path mapping in TypeScript without using a third-party for this problem. And without path-mapping if you ever want to move around your src/components/forms directory, you need to change 100 files. Or if you want to include a component in another one you'll need to walk barefoot using ../../!

Is this a new problem to solve from the scratch?

Absolutely NOT.

There are already a lot of third-party solutions just for this problem!

Is this going to be so new and hard to do in TSC world?

Absolutely NOT.

TSC provides path-aliases at the development time, it's just the way the output should be created.


Again, I have unblocked myself using a custom burger from Burger King! And it's going to cost me 5 minutes to copy/paste and set up the same custom third-party solutions in any new project. (Already done twice!)

I'm just watching here to see how Microsoft is treating its Typescript users and that will definitely shape my thoughts about Typescript for any future technical decision I'll make. :)

Thanks!

RyanCavanaugh commented 5 years ago

slowly backs away from keyboard

RyanCavanaugh commented 5 years ago

How is this thread so long without a single example of what the proposed transform is?

I'll also paste what I wrote elsewhere: Our general take on this is that you should write the import path that works at runtime, and set your TS flags to satisfy the compiler's module resolution step, rather than writing the import that works out-of-the-box for TS and then trying to have some other step "fix" the paths to what works at runtime.

We have about a billion flags that affect module resolutions already (baseUrl, path mapping, rootDir, outDir, etc). Trying to rewrite import paths "correctly" under all these schemes would be an endless nightmare.

RyanCavanaugh commented 5 years ago

IOW if there's some way where TS could allow you to write the path that you want emitted, that will always be the preferred solution. In general these are almost always possible with path mappings; if you have a scenario that can't be addressed with path mappings, that's the suggestion we're much more likely to be open to.

dannycochran commented 5 years ago

Hi folks -- OP here. Maybe chill a little. The vitriol / victimhood / name calling is really bizarre for a product that consistently releases new features and incorporates community feedback. FWIW, my solution to this was to stop using tsconfig paths and live with the ../../.. here and there. It's been fine. My codebase has not imploded.

How is this thread so long without a single example of what the proposed transform is?

@RyanCavanaugh This comment kind of illustrates what path we'd want emitted.

This alias:

# server/index.ts
import { foo } from '@common/helper';

Should get resolved to:

# server-build/server/index.js
const helper_1 = require('../common/helper');
const foo = helper_1.foo;

That presumes an outDir of server-build, which, when built, would look like this:

server-build
  common
    - helper.js
  server
    - index.js

tsconfig.json:

compilerOptions: {
  ...
  "paths": {
    "@common/*": [
      "./common/*"
    ]
  }
}
icopp commented 5 years ago

This is also closely related to #30952, which is basically the same thing as @dannycochran and @eyedean have noted above but for .d.ts files.

kitsonk commented 5 years ago

@dannycochran what rules should tsc follow to determine to rewrite?

# server/index.ts
import { foo } from '@common/helper';

Is the @ suggesting some sort of semantic meaning? That directly conflicts with Node.js resolution logic with namespaced packages. What would the tsconfig.json look like?

kitsonk commented 5 years ago

Also, if based on your first comment you expect paths to contained overloaded functionality, that would be a breaking change for a lot of other users of TypeScript who are trying to model what their runtime environment is looking like, the original intention of the poorly named paths argument (which was to model configurable loaders like AMD and SystemJS, and therefore copied the misleading name of such a configuration option there).

So you would need to propose introducing some sort of other variable that said "ignore the existing meaning of paths and resolve and rewrite the paths relative to something else", but also the feature would need to address where it isn't possible to express a relative path at runtime, and those who would need to mix runtime mapping and build time rewriting.

icopp commented 5 years ago

Also, if based on your first comment you expect paths to contained overloaded functionality

The functionality described in @dannycochran's comment is how paths already works. Something like this...

baseUrl: ".",
paths: {
  "~/*": ["src/*"]
}

...is already used by lots of people (including me) to make Typescript reflect the common uses or even default behavior of other Javascript tooling. (For example, the built-in ~ path alias in Parcel is effectively identical to the above for most use cases.)

Is the @ suggesting some sort of semantic meaning?

This is presumably...

baseUrl: ".",
paths: {
  "@common/*": ["src/*"]
}
kitsonk commented 5 years ago

The functionality described in @dannycochran's comment is how paths already works.

But it doesn't cause the import specifier to be rewritten. Taking away just the ability to remap locations of modules that will be located different during runtime, which is what the intent of paths is today needs to co-exist. Just putting a flag that says "rewrite" module specifiers wouldn't be a good idea, because as soon as you do that, someone will say they want remapping and rewriting at the same time.

This is presumably...

I think if this has any chance, presuming wouldn't be sufficient.

wintercounter commented 5 years ago

So a simple question: How we should ship libraries while using paths? Short answer: We can't by default.

To be fair, Babel doesn't support such either, I have to use a separate plugin to resolve my alieses. BUT at least it is able to have a plugin!

RyanCavanaugh commented 5 years ago

How would you ship a JavaScript library whose import paths don't work in the context of another program? It's the same question and has similarly few answers.

wintercounter commented 5 years ago

That's exactly the point. Currently it doesn't work. It only can work if those paths are being resolved.

kitsonk commented 5 years ago

Yeah, that is what I am struggling with here too...

Potential use cases for a library:

  1. One that will run under node. If this case, best to leverage node module resolution fully instead of trying to invent your own. node doesn't have a configurable loader. That is life.
  2. Running in a browser or node as a standalone library. If this is the case, you should use some sort of bundler, like rollup, webpack, Parcel, etc. Using paths might help make bundling easier, but unlikely, best to leverage your packager to output the standalone versions you need. Being a complete build tool is not a goal of TypeScript.
  3. Running browser only, using an AMD or SystemJS loader. You have one design time paths of which you have to inform your consumer on how to integrate that into a larger loader configuration at run time, but likely can releverage your paths.
  4. Loading ES Modules directly in a browser (or Deno). Use import-map (or the polyfill) and again, essentially the paths.

tsc is not a bundler, never will be a bundler (or a full featured build tool)... that means it will never know enough, nor want to know enough to properly re-write the module specifiers. It understands Node.js resolution, but again, that is design time mirroring of what is expected to be valid at runtime. For tsc rewriting can only be write for a very narrow set of uses cases and most of the time it would be just wrong.

Just repeatedly saying "its a bug, fix it" without addressing the specific questions raised to any proposal in really not going to make anything move forward. Proposing something that a) preserves existing functionality that people are depending on and b) can be usable with exemplar use cases is about the only way this will move forward.

wintercounter commented 5 years ago

For my specific case the biggest issue here are d.ts files. No bundler is going to help to "bundle"/resolve their imports.

I understand the concerns behind implementing such feature but seems like it's a valid use case for many of us. If tsc's plugin system would provide us an interface where we can manipulate the emitted path that would solve the problem for many of us I think. tsc can stay pure that way.

On Tue, Aug 27, 2019, 06:30 Kitson Kelly notifications@github.com wrote:

Yeah, that is what I am struggling with here too...

Potential use cases for a library:

  1. One that will run under node. If this case, best to leverage node module resolution fully instead of trying to invent your own. node doesn't have a configurable loader. That is life.
  2. Running in a browser or node as a standalone library. If this is the case, you should use some sort of bundler, like rollup, webpack, Parcel, etc. Using paths might help make bundling easier, but unlikely, best to leverage your packager to output the standalone versions you need. Being a complete build tool is not a goal of TypeScript.
  3. Running browser only, using an AMD or SystemJS loader. You have one design time paths of which you have to inform your consumer on how to integrate that into a larger loader configuration at run time, but likely can releverage your paths.
  4. Loading ES Modules directly in a browser (or Deno). Use import-map (or the polyfill) and again, essentially the paths.

tsc is not a bundler, never will be a bundler (or a full featured build tool)... that means it will never know enough, nor want to know enough to properly re-write the module specifiers. It understands Node.js resolution, but again, that is design time mirroring of what is expected to be valid at runtime. For tsc rewriting can only be write for a very narrow set of uses cases and most of the time it would be just wrong.

Just repeatedly saying "its a bug, fix it" without addressing the specific questions raised to any proposal in really not going to make anything move forward. Proposing something that a) preserves existing functionality that people are depending on and b) can be usable with exemplar use cases is about the only way this will move forward.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/microsoft/TypeScript/issues/26722?email_source=notifications&email_token=AAHLJQHBP5BWREGJBL2Q2W3QGSUVVA5CNFSM4FSCEI7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5GOA6Y#issuecomment-525131899, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLJQHD64R4EUVR5RZAWF3QGSUVVANCNFSM4FSCEI7A .

ark120202 commented 5 years ago

A new Node.js proposal, proposal-pkg-exports, adds a new import field to package.json that seems to cover the most common use case there. If it would be accepted and TypeScript would use it for type resolution (I guess it can be tracked as a part of #33079) it would be possible to create local aliases in a simpler and more compatible way (webpack might support it as well), while paths option would be able to keep it's current meaning - reflecting non-standard runtime resolution behavior.

arsamsarabi commented 5 years ago

I am sorry to see that this issue is not receiving the attention it needs after over a year. This is a real problem and I don't understand why @eyedean 's proposal has fallen on deaf ears.

RyanCavanaugh commented 5 years ago

We're listening and have repeatedly, repeatedly, repeatedly explained in multiple threads why this proposal and similar ones go against our main goals about how module paths should work in TypeScript.

Not getting what you want doesn't mean the other person in the conversation isn't listening.