Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
81c9518
Fix getResolvePackageJsonImports utility (#61707)
andrewbranch May 16, 2025
b504a1e
Handle lock file 3 version when caching the typings ensuring we can r…
sheetalkamat May 21, 2025
44d4671
Update pr_owners.txt (#61798)
jakebailey Jun 3, 2025
3dd0a35
Initialize the map for dts to reference and source to reference when …
sheetalkamat Jun 4, 2025
2b88aeb
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 4, 2025
a591ca3
fix(61747): for (using of = is incorrectly parsed (#61764)
a-tarasyuk Jun 5, 2025
ac03ba4
fix(checker): report error when using bigint as enum key (#61777)
magic-akari Jun 5, 2025
cd34199
tsc --init update (#61813)
RyanCavanaugh Jun 6, 2025
a69c6d0
Add support for `import defer` proposal (#60757)
nicolo-ribaudo Jun 6, 2025
ffd98c1
feat: add Error.isError() to ESNext lib (#60788)
dirkluijk Jun 6, 2025
51dcd90
Cache mapper instantiations (#61505)
Andarist Jun 6, 2025
652ed7f
Add lib.esnext.sharedmemory (#61646)
Renegade334 Jun 6, 2025
1e24945
explicitly disallow `using` in ambient contexts (#61781)
Renegade334 Jun 6, 2025
fa2a0fc
Issue "'{0}' declarations can only be declared inside a block." for b…
Andarist Jun 6, 2025
7715955
Fix helpers emit for .cjs files in ESM module mode (#61814)
andrewbranch Jun 6, 2025
355b9e0
Avoid resolving source prop type when the target is `unknown`/`any` (…
Andarist Jun 6, 2025
97cfa26
optimization, reduce memory usage (#61822)
VincentBailly Jun 9, 2025
cb38d99
Add `--module node20` (#61805)
andrewbranch Jun 9, 2025
34d1ea6
Fix type variable leaks and cache inconsistencies (#61668)
ahejlsberg Jun 9, 2025
0dfd0c2
Restore `import defer =` parsing (#61837)
nicolo-ribaudo Jun 9, 2025
12e09f4
Port "Improve type discrimination algorithm" from tsgo (#61828)
jakebailey Jun 9, 2025
529ed09
fix link to "Help Wanted" issues (#61843)
AllenSH12 Jun 11, 2025
dd1e258
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 11, 2025
f1d2494
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 17, 2025
5a3271b
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add support for import defer proposal (microsoft#60757)
Co-authored-by: Ujjwal Sharma <ryzokuken@disroot.org>
Co-authored-by: Nicolò Ribaudo <hell@nicr.dev>
  • Loading branch information
3 people authored Jun 6, 2025
commit a69c6d0bb7a382538c8bbbecfb96431badb5c873
71 changes: 58 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10247,7 +10247,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
/*isTypeOnly*/ false,
/*phaseModifier*/ undefined,
/*name*/ undefined,
factory.createNamedImports([factory.createImportSpecifier(
/*isTypeOnly*/ false,
Expand Down Expand Up @@ -10344,7 +10344,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addResult(
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined),
factory.createImportClause(
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
factory.createIdentifier(localName),
/*namedBindings*/ undefined,
),
specifier,
attributes,
),
Expand All @@ -10360,7 +10364,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addResult(
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))),
factory.createImportClause(
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
/*name*/ undefined,
factory.createNamespaceImport(factory.createIdentifier(localName)),
),
specifier,
(node as ImportClause).parent.attributes,
),
Expand Down Expand Up @@ -10389,7 +10397,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
isTypeOnly,
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
/*name*/ undefined,
factory.createNamedImports([
factory.createImportSpecifier(
Expand Down Expand Up @@ -38014,6 +38022,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

if (node.keywordToken === SyntaxKind.ImportKeyword) {
if (node.name.escapedText === "defer") {
Debug.assert(!isCallExpression(node.parent) || node.parent.expression !== node, "Trying to get the type of `import.defer` in `import.defer(...)`");
return errorType;
}
return checkImportMetaProperty(node);
}

Expand Down Expand Up @@ -41452,7 +41464,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
// Optimize for the common case of a call to a function with a single non-generic call
// signature where we can just fetch the return type without checking the arguments.
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !isSymbolOrSymbolForCall(expr)) {
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !isSymbolOrSymbolForCall(expr) && !isImportCall(expr)) {
return isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) :
getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression));
}
Expand Down Expand Up @@ -41606,8 +41618,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case SyntaxKind.ElementAccessExpression:
return checkIndexedAccess(node as ElementAccessExpression, checkMode);
case SyntaxKind.CallExpression:
if ((node as CallExpression).expression.kind === SyntaxKind.ImportKeyword) {
return checkImportCallExpression(node as ImportCall);
if (isImportCall(node)) {
return checkImportCallExpression(node);
}
// falls through
case SyntaxKind.NewExpression:
Expand Down Expand Up @@ -49877,6 +49889,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return isExportAssignment(node.parent) ? Debug.checkDefined(node.parent.symbol) : undefined;

case SyntaxKind.ImportKeyword:
if (isMetaProperty(node.parent) && node.parent.name.escapedText === "defer") {
return undefined;
}
// falls through
case SyntaxKind.NewKeyword:
return isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined;
case SyntaxKind.InstanceOfKeyword:
Expand Down Expand Up @@ -52851,7 +52867,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
break;
case SyntaxKind.ImportKeyword:
if (escapedText !== "meta") {
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta");
const isCallee = isCallExpression(node.parent) && node.parent.expression === node;
if (escapedText === "defer") {
if (!isCallee) {
return grammarErrorAtPos(node, node.end, 0, Diagnostics._0_expected, "(");
}
}
else {
if (isCallee) {
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer, unescapeLeadingUnderscores(node.name.escapedText));
}
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta");
}
}
break;
}
Expand Down Expand Up @@ -53110,11 +53137,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function checkGrammarImportClause(node: ImportClause): boolean {
if (node.isTypeOnly && node.name && node.namedBindings) {
return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both);
if (node.phaseModifier === SyntaxKind.TypeKeyword) {
if (node.name && node.namedBindings) {
return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both);
}
if (node.namedBindings?.kind === SyntaxKind.NamedImports) {
return checkGrammarNamedImportsOrExports(node.namedBindings);
}
}
if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) {
return checkGrammarNamedImportsOrExports(node.namedBindings);
else if (node.phaseModifier === SyntaxKind.DeferKeyword) {
if (node.name) {
return grammarErrorOnNode(node, Diagnostics.Default_imports_are_not_allowed_in_a_deferred_import);
}
if (node.namedBindings?.kind === SyntaxKind.NamedImports) {
return grammarErrorOnNode(node, Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import);
}
if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.Preserve) {
return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_preserve);
}
}
return false;
}
Expand All @@ -53137,7 +53177,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return grammarErrorOnNode(node, Diagnostics.ESM_syntax_is_not_allowed_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled);
}

if (moduleKind === ModuleKind.ES2015) {
if (node.expression.kind === SyntaxKind.MetaProperty) {
if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.Preserve) {
return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_preserve);
}
}
else if (moduleKind === ModuleKind.ES2015) {
return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_node18_or_nodenext);
}

Expand Down
16 changes: 16 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -8487,5 +8487,21 @@
"String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": {
"category": "Error",
"code": 18057
},
"Default imports are not allowed in a deferred import.": {
"category": "Error",
"code": 18058
},
"Named imports are not allowed in a deferred import.": {
"category": "Error",
"code": 18059
},
"Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'preserve'.": {
"category": "Error",
"code": 18060
},
"'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?": {
"category": "Error",
"code": 18061
}
}
4 changes: 2 additions & 2 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3686,8 +3686,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}

function emitImportClause(node: ImportClause) {
if (node.isTypeOnly) {
emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node);
if (node.phaseModifier !== undefined) {
emitTokenWithComment(node.phaseModifier, node.pos, writeKeyword, node);
writeSpace();
}
emit(node.name);
Expand Down
20 changes: 14 additions & 6 deletions src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ import {
ImportClause,
ImportDeclaration,
ImportEqualsDeclaration,
ImportPhaseModifierSyntaxKind,
ImportSpecifier,
ImportTypeAssertionContainer,
ImportTypeNode,
Expand Down Expand Up @@ -4723,26 +4724,33 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}

// @api
function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause {
function createImportClause(phaseModifier: ImportPhaseModifierSyntaxKind | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause {
const node = createBaseDeclaration<ImportClause>(SyntaxKind.ImportClause);
node.isTypeOnly = isTypeOnly;
if (typeof phaseModifier === "boolean") {
phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined;
}
node.isTypeOnly = phaseModifier === SyntaxKind.TypeKeyword;
node.phaseModifier = phaseModifier;
node.name = name;
node.namedBindings = namedBindings;
node.transformFlags |= propagateChildFlags(node.name) |
propagateChildFlags(node.namedBindings);
if (isTypeOnly) {
if (phaseModifier === SyntaxKind.TypeKeyword) {
node.transformFlags |= TransformFlags.ContainsTypeScript;
}
node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context
return node;
}

// @api
function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) {
return node.isTypeOnly !== isTypeOnly
function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifierSyntaxKind | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) {
if (typeof phaseModifier === "boolean") {
phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined;
}
return node.phaseModifier !== phaseModifier
|| node.name !== name
|| node.namedBindings !== namedBindings
? update(createImportClause(isTypeOnly, name, namedBindings), node)
? update(createImportClause(phaseModifier, name, namedBindings), node)
: node;
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node

const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration(
/*modifiers*/ undefined,
nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings),
nodeFactory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, namedBindings),
nodeFactory.createStringLiteral(externalHelpersModuleNameText),
/*attributes*/ undefined,
);
Expand Down
Loading