From a510cad873dbb5b033e7cc2c8e7a7bd8edbbeebe Mon Sep 17 00:00:00 2001 From: Alexander T Date: Tue, 17 Mar 2020 22:21:20 +0200 Subject: [PATCH] fix(36936): fix crash caused by resolving non existent export (#37077) --- src/compiler/checker.ts | 4 +- .../tsxResolveExternalModuleExportsTypes.js | 26 ++++++++++++ ...xResolveExternalModuleExportsTypes.symbols | 42 +++++++++++++++++++ ...tsxResolveExternalModuleExportsTypes.types | 38 +++++++++++++++++ .../tsxResolveExternalModuleExportsTypes.ts | 24 +++++++++++ 5 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/tsxResolveExternalModuleExportsTypes.js create mode 100644 tests/baselines/reference/tsxResolveExternalModuleExportsTypes.symbols create mode 100644 tests/baselines/reference/tsxResolveExternalModuleExportsTypes.types create mode 100644 tests/cases/compiler/tsxResolveExternalModuleExportsTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1bd276310e7..1a765e54897 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3095,8 +3095,8 @@ namespace ts { function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol; function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined; function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol { - if (moduleSymbol) { - const exportEquals = resolveSymbol(moduleSymbol.exports!.get(InternalSymbolName.ExportEquals), dontResolveAlias); + if (moduleSymbol?.exports) { + const exportEquals = resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.ExportEquals), dontResolveAlias); const exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol)); return getMergedSymbol(exported) || moduleSymbol; } diff --git a/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.js b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.js new file mode 100644 index 00000000000..e9aa4de50a1 --- /dev/null +++ b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/tsxResolveExternalModuleExportsTypes.ts] //// + +//// [index.d.ts] +declare var a: a.Foo; +declare namespace a { + interface Foo {} +} +export = a; + +//// [index.d.ts] +import * as a from 'a'; +declare module 'a' { + namespace Test {} + + interface Foo { + Test: null; + } +} + +//// [foo.tsx] +import { Test } from 'a'; +const Foo = (

); + + +//// [foo.jsx] +var Foo = (

); diff --git a/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.symbols b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.symbols new file mode 100644 index 00000000000..3524c5b9d3b --- /dev/null +++ b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.symbols @@ -0,0 +1,42 @@ +=== /node_modules/@types/a/index.d.ts === +declare var a: a.Foo; +>a : Symbol(a, Decl(index.d.ts, 0, 11), Decl(index.d.ts, 0, 21), Decl(index.d.ts, 0, 23)) +>a : Symbol(a, Decl(index.d.ts, 0, 11), Decl(index.d.ts, 0, 21)) +>Foo : Symbol(a.Foo, Decl(index.d.ts, 1, 21)) + +declare namespace a { +>a : Symbol(a, Decl(index.d.ts, 0, 11), Decl(index.d.ts, 0, 21), Decl(index.d.ts, 0, 23)) + + interface Foo {} +>Foo : Symbol(Foo, Decl(index.d.ts, 1, 21), Decl(index.d.ts, 2, 21)) +} +export = a; +>a : Symbol(a, Decl(index.d.ts, 0, 11), Decl(index.d.ts, 0, 21)) + +=== /node_modules/@types/b/index.d.ts === +import * as a from 'a'; +>a : Symbol(a, Decl(index.d.ts, 0, 6)) + +declare module 'a' { +>'a' : Symbol(a, Decl(index.d.ts, 0, 11), Decl(index.d.ts, 0, 21), Decl(index.d.ts, 0, 23)) + + namespace Test {} +>Test : Symbol(Test, Decl(index.d.ts, 1, 20)) + + interface Foo { +>Foo : Symbol(Foo, Decl(index.d.ts, 1, 21), Decl(index.d.ts, 2, 21)) + + Test: null; +>Test : Symbol(Foo.Test, Decl(index.d.ts, 4, 19)) + } +} + +=== tests/cases/compiler/foo.tsx === +import { Test } from 'a'; +>Test : Symbol(Test, Decl(foo.tsx, 0, 8)) + +const Foo = (

); +>Foo : Symbol(Foo, Decl(foo.tsx, 1, 5)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47)) + diff --git a/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.types b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.types new file mode 100644 index 00000000000..d954fe61ce7 --- /dev/null +++ b/tests/baselines/reference/tsxResolveExternalModuleExportsTypes.types @@ -0,0 +1,38 @@ +=== /node_modules/@types/a/index.d.ts === +declare var a: a.Foo; +>a : import("/node_modules/@types/a/index.d.ts").Foo +>a : any + +declare namespace a { + interface Foo {} +} +export = a; +>a : import("/node_modules/@types/a/index.d.ts").Foo + +=== /node_modules/@types/b/index.d.ts === +import * as a from 'a'; +>a : a.Foo + +declare module 'a' { +>'a' : Foo + + namespace Test {} + + interface Foo { + Test: null; +>Test : null +>null : null + } +} + +=== tests/cases/compiler/foo.tsx === +import { Test } from 'a'; +>Test : null + +const Foo = (

); +>Foo : JSX.Element +>(

) : JSX.Element +>

: JSX.Element +>h1 : any +>h1 : any + diff --git a/tests/cases/compiler/tsxResolveExternalModuleExportsTypes.ts b/tests/cases/compiler/tsxResolveExternalModuleExportsTypes.ts new file mode 100644 index 00000000000..e8cfb6aa4e5 --- /dev/null +++ b/tests/cases/compiler/tsxResolveExternalModuleExportsTypes.ts @@ -0,0 +1,24 @@ +// @module: ES2015 +// @jsx: preserve +// @libFiles: react.d.ts,lib.d.ts + +// @Filename: /node_modules/@types/a/index.d.ts +declare var a: a.Foo; +declare namespace a { + interface Foo {} +} +export = a; + +// @Filename: /node_modules/@types/b/index.d.ts +import * as a from 'a'; +declare module 'a' { + namespace Test {} + + interface Foo { + Test: null; + } +} + +// @Filename: foo.tsx +import { Test } from 'a'; +const Foo = (

);