From 831d7718006fbc01ca97b3eef8992388381eec22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 19:03:28 +0100 Subject: [PATCH] Do not consider `import.defer` in `import.defer(...)` as an expression --- src/compiler/checker.ts | 13 +++++++++++-- src/compiler/utilities.ts | 4 +++- .../dynamicImportDefer(module=commonjs).types | 2 -- .../dynamicImportDefer(module=es2015).types | 2 -- .../dynamicImportDefer(module=es2020).types | 2 -- .../dynamicImportDefer(module=esnext).types | 1 - .../dynamicImportDefer(module=nodenext).types | 1 - 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0fda4405f53eb..a91df371f2914 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37607,7 +37607,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.keywordToken === SyntaxKind.ImportKeyword) { if (node.name.escapedText === "defer") { - // 'checkGrammarMetaProperty' already reported the error for the standalone import.defer. + Debug.assert(!isCallExpression(node.parent) || node.parent.expression !== node, "Trying to get the type of `import.defer` in `import.defer(...)`"); return errorType; } else { return checkImportMetaProperty(node); @@ -41023,7 +41023,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)); } @@ -49681,6 +49681,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: @@ -49753,7 +49757,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isExpressionNode(node)) { + try { return getRegularTypeOfExpression(node as Expression); + } catch (e) { + console.error("Error while getting the type of", isExpressionNode(node), node.kind, (node as MetaProperty).keywordToken !== SyntaxKind.ImportKeyword, (node as MetaProperty).name?.escapedText) + throw e; + } } if (classType && !classDecl.isImplements) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6c65fb2005d1c..e362baa10eb52 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3589,8 +3589,10 @@ export function isExpressionNode(node: Node): boolean { case SyntaxKind.JsxFragment: case SyntaxKind.YieldExpression: case SyntaxKind.AwaitExpression: - case SyntaxKind.MetaProperty: return true; + case SyntaxKind.MetaProperty: + // `import.defer` in `import.defer(...)` is not an expression + return !isImportCall(node.parent) || node.parent.expression !== node; case SyntaxKind.ExpressionWithTypeArguments: return !isHeritageClause(node.parent) && !isJSDocAugmentsTag(node.parent); case SyntaxKind.QualifiedName: diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).types b/tests/baselines/reference/dynamicImportDefer(module=es2015).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).types b/tests/baselines/reference/dynamicImportDefer(module=es2020).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).types b/tests/baselines/reference/dynamicImportDefer(module=esnext).types index 2681338e94c4f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=esnext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).types @@ -26,7 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : error >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types index a4138d6f831ce..415047482d3c5 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types @@ -26,7 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : error >defer : any > : ^^^ >"./a.js" : "./a.js"