-
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
Don't allow .ts
to appear in an import
#9646
Conversation
I would not put error reporting into module resolution but instead report error in program if resolved module ended up to be .ts file |
@@ -1943,6 +1943,10 @@ | |||
"category": "Error", | |||
"code": 2689 | |||
}, | |||
"Module name should not include a '.ts' extension: '{0}'.": { |
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.
Try making this
An import path should not include a '.ts' extension. Consider importing '{0}' instead.
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.
An import path should not end with a '{0}' extension. Consider importing '{1}' instead.
Since this error is being used for .tsx
as well.
return forEach(supportedTypeScriptExtensionsNonDts, extension => fileExtensionIs(fileName, extension)); | ||
/** Return ".ts" or ".tsx" if that is the extension. */ | ||
export function tryExtractTypeScriptExtensionNonDts(fileName: string): string | undefined { | ||
return find(supportedTypeScriptExtensionsNonDts, extension => fileExtensionIs(fileName, extension)); |
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.
Don't you want to give the same error if you use .d.ts
as well?
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.
Also, can you add a test that imports from a file ending in .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.
If people add a .d.ts
extension they may be doing unnecessary work, but it won't cause runtime errors because declaration references don't translate to imports in the output. In contrast, a .ts
extension will either fail to import (because the output file has a .js
extension) or ask the JS engine to load typescript code.
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.
If people add a .d.ts extension they may be doing unnecessary work, but it won't cause runtime errors because declaration references don't translate to imports in the output.
.d.ts
imports don't just get elided. If you use any imported entities as values, then we still emit the import itself. Try it out:
foo.d.ts
export declare var foo;
bar.ts
import * as v from "./foo.d.ts";
v.foo;
The current emit for bar.js
is
"use strict";
var v = require("./foo.d.ts");
v.foo;
The latest commit would mean we no longer allow a package.json "typings" to specify "foo" when the typings are in "foo.d.ts". We have no tests that relied on that behavior, and it doesn't seem to be a style we've recommended, but still, it's a breaking change. According to the spec at #2338, it looks like it requires that the package.json "typings" not have an extension — |
@@ -109,6 +109,17 @@ namespace ts { | |||
return undefined; | |||
} | |||
|
|||
/** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ | |||
export function tryFind<T>(array: T[], predicate: (element: T, index: number) => boolean): T | undefined { |
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.
Hmm, I expected find
to have the type that tryFind
has right now. Why does find
take callback
and not predicate
?
I forgot to mention it when I ran into it last week while trying to use find
.
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.
If we rename tryFind
to find
, what should we call find
? mustFind
?
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.
findMap
? Let me go see if this function is in hoogle...
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 the equivalent of bind (>>=
) or something like Data.Foldable.concatMap
except that it takes Array<T>
to Exception<T>
. So, yeah, findMap
is not bad, or mapFirst
or mapSingle
.
👍 |
@@ -2713,6 +2713,13 @@ namespace ts { | |||
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); | |||
} | |||
|
|||
/** Return ".ts" or ".tsx" if that is the extension. */ |
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.
".d.ts"?
@andy-ms This change in 359c8b1 breaks vscode extensions as vscode uses an extensionless path for |
I filed microsoft/vscode-languageserver-node#76 to track this issue for vscode. |
Fixes #9538
I'd like for us to issue an error specific to this issue, because people will be confused if we just output that we can't find
./foo.ts
and they see that it's right there.Unfortunately I'm not sure how to hook up
loadModuleFromFile
to the error diagnostics system (as opposed to resolution tracing), can anyone help with this?