-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Support 'import.meta' #23327
Support 'import.meta' #23327
Conversation
…obal augmentations.
src/lib/es5.d.ts
Outdated
@@ -505,6 +505,10 @@ interface TemplateStringsArray extends ReadonlyArray<string> { | |||
readonly raw: ReadonlyArray<string>; | |||
} | |||
|
|||
interface ImportMeta { | |||
[propertyName: string]: any; |
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.
There is no way to opt out of this one... users who want strict definition can not undo the index signature. consider not adding it and letting say node.d.ts add it.
src/compiler/parser.ts
Outdated
} | ||
|
||
function walkTreeForExternalModuleIndicators(node: Node): Node { | ||
return isAnExternalModuleIndicatorNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators); |
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.
This can accidentally pick up an import/export from an module augmentation as the current file's externalModuleIndicator
if we're not careful.
declare module "foo" {
import * as blah from "blah"
}
import.meta
331230d
to
28f8d75
Compare
Heya, we are using stackblitz to host our documentation demos on our site before Google I/O, and we believe that we are blocked on this issue. Do you know which typescript release this fix would be included in? CC: @EricSimons @justinfagnani Relevant issues: |
2.9 would be our next feature release, which should be cut sometime near the end of May. |
src/compiler/parser.ts
Outdated
// and possibly nested import statements in the future). | ||
// Ideally the first few statements will be an import/export anyway. | ||
sourceFile.externalModuleIndicator = | ||
!(sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ? |
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 this should be:
sourceFile.externalModuleIndicator = forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || getImportMetaNode(sourceFile);
function isAnExternalModuleIndicatorNode(node: Node) {
return hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
|| node.kind === SyntaxKind.ExportDeclaration
? node
: undefined
}
function isImportMetaNode(node: Node) {
return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta";
}
function walkTreeForExternalModuleIndicators(node: Node): Node {
return isImportMetaNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
}
function getImportMetaNode(node: SourceFile) {
return (sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ? walkTreeForExternalModuleIndicators(node) : undefined;
}
Please take a look at the checklist in https://github.com/Microsoft/TypeScript/wiki/Release-Activities#new-syntax-introduced. we need to add colorization support as well. |
We can get this in first and discuss relaxing the restriction after. |
Fixes #22861. This PR introduces support for
import.meta
, a meta-property described here.Here are some details on the implementation.
The ImportMeta Interface
The type of
import.meta
is the globalImportMeta
type which is defined inlib.es5.d.ts
:This interface is extremely limited. Adding well-known properties for Node or browsers requires interface merging and possibly a global augmentation depending on the context.
For example, one might want to say that
__dirname
is always available onimport.meta
:Any user of the above
.d.ts
file will be able to get completions forimport.meta.__dirname
which has the typestring
.Alternatively, you might be in a bind and just need to say "yes, I know
import.meta
will have this property, and I only need to use it in one file":An earlier version of this pull request defined
ImportMeta
as follows:However, this interface is extremely lax, and means that you can misspell any property.
Community feedback is appreciated here.
Targets
import.meta
is only allowed when targeting ESNext modules and ECMAScript targets.I think it might make sense to say "this only runs on ESNext modules, but can run on any target", but I'd rather be conservative for now.
Incremental Parsing
import.meta
is only valid within a module. This implies one of two things:import.meta
if the current module does not contain a module indicator (i.e. the module has no imports/exports).import.meta
itself is a module indicator (which turns the current file into a module).I went with choice (2), which implies that a module indicator can occur anywhere within the file. To avoid a full walk of the tree, I use a new NodeFlag called
PossiblyContainsImportMeta
. Much likeNodeFlags.PossiblyContainsDynamicImport
, this new flag is set exactly once, and is never unset when re-using an AST.When the flag is set, we will do a full walk of the AST to find module indicators, but in the common case, we'll run into an
import
orexport
declaration.