From 8f8a579eee719bd2c95c7a0b0e27de4f0bdc14aa Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Wed, 31 Mar 2021 18:18:16 -0700 Subject: [PATCH] Added BindingElement to isSomeImportDeclaration (#43387) * Added BindingElement to isSomeImportDeclaration * Added tests * Refactores to use getDeclarationOfAlias --- src/compiler/checker.ts | 18 ++------------ ...onJsImportBindingElementNarrowType.symbols | 20 ++++++++++++++++ ...mmonJsImportBindingElementNarrowType.types | 24 +++++++++++++++++++ .../commonJsImportBindingElementNarrowType.ts | 15 ++++++++++++ 4 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/commonJsImportBindingElementNarrowType.symbols create mode 100644 tests/baselines/reference/commonJsImportBindingElementNarrowType.types create mode 100644 tests/cases/conformance/externalModules/commonJsImportBindingElementNarrowType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 726690dd48f..4201853d856 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2489,6 +2489,7 @@ namespace ts { * module.exports = * {} * {name: } + * const { x } = require ... */ function isAliasSymbolDeclaration(node: Node): boolean { return node.kind === SyntaxKind.ImportEqualsDeclaration @@ -23933,7 +23934,7 @@ namespace ts { } } else if (isAlias) { - declaration = symbol.declarations?.find(isSomeImportDeclaration); + declaration = getDeclarationOfAliasSymbol(symbol); } else { return type; @@ -41950,21 +41951,6 @@ namespace ts { } } - function isSomeImportDeclaration(decl: Node): boolean { - switch (decl.kind) { - case SyntaxKind.ImportClause: // For default import - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportSpecifier: // For rename import `x as y` - return true; - case SyntaxKind.Identifier: - // For regular import, `decl` is an Identifier under the ImportSpecifier. - return decl.parent.kind === SyntaxKind.ImportSpecifier; - default: - return false; - } - } - namespace JsxNames { export const JSX = "JSX" as __String; export const IntrinsicElements = "IntrinsicElements" as __String; diff --git a/tests/baselines/reference/commonJsImportBindingElementNarrowType.symbols b/tests/baselines/reference/commonJsImportBindingElementNarrowType.symbols new file mode 100644 index 00000000000..4410ae92d6a --- /dev/null +++ b/tests/baselines/reference/commonJsImportBindingElementNarrowType.symbols @@ -0,0 +1,20 @@ +=== /bar.js === +const { a } = require("./foo"); +>a : Symbol(a, Decl(bar.js, 0, 7)) +>require : Symbol(require) +>"./foo" : Symbol("/foo", Decl(foo.d.ts, 0, 0)) + +if (a) { +>a : Symbol(a, Decl(bar.js, 0, 7)) + + var x = a + 1; +>x : Symbol(x, Decl(bar.js, 2, 5)) +>a : Symbol(a, Decl(bar.js, 0, 7)) +} +=== /foo.d.ts === +// Regresion test for GH#41957 + + +export const a: number | null; +>a : Symbol(a, Decl(foo.d.ts, 3, 12)) + diff --git a/tests/baselines/reference/commonJsImportBindingElementNarrowType.types b/tests/baselines/reference/commonJsImportBindingElementNarrowType.types new file mode 100644 index 00000000000..6eff02b733f --- /dev/null +++ b/tests/baselines/reference/commonJsImportBindingElementNarrowType.types @@ -0,0 +1,24 @@ +=== /bar.js === +const { a } = require("./foo"); +>a : number | null +>require("./foo") : typeof import("/foo") +>require : any +>"./foo" : "./foo" + +if (a) { +>a : number | null + + var x = a + 1; +>x : number +>a + 1 : number +>a : number +>1 : 1 +} +=== /foo.d.ts === +// Regresion test for GH#41957 + + +export const a: number | null; +>a : number | null +>null : null + diff --git a/tests/cases/conformance/externalModules/commonJsImportBindingElementNarrowType.ts b/tests/cases/conformance/externalModules/commonJsImportBindingElementNarrowType.ts new file mode 100644 index 00000000000..a98fdc3ef67 --- /dev/null +++ b/tests/cases/conformance/externalModules/commonJsImportBindingElementNarrowType.ts @@ -0,0 +1,15 @@ +// Regresion test for GH#41957 + +// @allowJs: true +// @checkJs: true +// @strictNullChecks: true +// @noEmit: true + +// @Filename: /foo.d.ts +export const a: number | null; + +// @Filename: /bar.js +const { a } = require("./foo"); +if (a) { + var x = a + 1; +} \ No newline at end of file