-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Always allow type-only imports to reference .ts extensions #54746
Conversation
// @target: esnext | ||
// @module: esnext | ||
|
||
// @Filename: a.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there already an equivalent test case of the 5 assertions below for the case where a.ts
is a.d.ts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so, but I'll add one here so it can be compared easily
import {} from "./a.ts"; // error | ||
~~~~~~~~ | ||
!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. | ||
import { type A as _A } from "./a.ts"; // error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting i would have expected above two to be not errors per your description since its not in emitted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s a bit of a gray area, but I decided to treat this as if verbatimModuleSyntax
is enabled. Depending on settings, this import could get preserved as import {} from "./a.ts"
, whereas import type
is unambiguously elided. It feels better to rely on the strong, unambiguous signal that the import will always be elided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this is effectively always a bad idea; if you ever want to update an import to include something that isn't a type, you now have to rewrite the import path, when you could have just written the import the correct way the first time.
Am I missing a use-case here? I don't find the comment in #51876 (comment) very compelling and it seems to be wanting to resolve .ts
for non-type reasons... Ignoring all of our arguments as to why we want imports written as they are to be emitted, not what necessarily is on disk at the time.
I guess if this is the intended behavior then it seems fine, but I do feel like nobody should be doing this, and everyone who does is just going to be confused and complain that TS is doing something wrong (when, we aren't, as is usual for every module resolution "bug").
I don’t find the “you have to rewrite the module specifier to include a non-type” argument very compelling, because the main thing you have to do to reference the things you import in value positions is remove the I personally find it weird to see an import like import type { SomeType } from "./types.js" Many people always find /// <reference path="fourslash.js" /> |
Concretely, the transition I'm referring to is when one has the import: import type { Blah } from "./something.ts" If they previously only used My understanding is that auto-import or quickfix will attempt to reuse this import declaration, meaning they'll just drop the If auto-import/quickfix don't do this, then they'll instead introduce duplicate import declarations, in which case future imports/fixes will have to ambiguously distribute over multiple imports, which sounds weird.
With |
Yeah, your message made me realize that auto-imports needs to handle this for you if it doesn’t already. Auto-imports is never supposed to result in an error. That should be an easy fix.
The part that I meant was weird about that was the |
After doing some development for arethetypeswrong in JSDoc, I’m even more convinced that this is desirable. Some JSDoc-annotated JS files reference a types file that’s in some scripts that get executed with /** @type {import("./types.js").Foo} */ instead of /** @type {import("./types.ts").Foo} */ And in this case, I definitely should not enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does seem like the upsides outweigh the downsides given the above, though I do think we need to file an issue for or fix soon the fact that auto-imports may misbehave when this is allowed. At least nobody would have written this so far.
Is this still good to go in pre-RC or does it need to wait?
I think this can go in pre-RC since it only removes an error and otherwise doesn’t change any behavior. I can fix the auto-import behavior as part of this PR. |
…t declarations without `allowImportingTsExtensions`
@jakebailey auto-imports changes are done; thanks for the reminder 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto-imports look good to me, thanks!
Currently, it’s an error to have a type-only import from a
.ts
extension unlessallowImportingTsExtensions
is enabled:I’m pretty sure this was an oversight in #51669/#52230 where I first introduced
allowImportingTsExtensions
. Whether the flag is set or not, type-only imports are allowed to import from a.d.ts
extension, so it makes sense to allow it for.ts
extensions too. What I intended to implement was:allowImportingTsExtensions
removes the “as long as it doesn’t emit to JS” exception from (2)This was brought up as a complaint in #51876.