diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6ece23f022ab3..12637d76b2e1e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5350,7 +5350,7 @@ namespace ts { // so we don't even have placeholders to fill in. if (length(realMembers)) { const localName = getInternalSymbolName(symbol, symbolName); - serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, /*suppressNewPrivateContext*/ false); + serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & SymbolFlags.Function)); } if (length(mergedMembers)) { const localName = getInternalSymbolName(symbol, symbolName); @@ -5593,7 +5593,10 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(createIdentifier(localName), /*namedBindings*/ undefined), - createLiteral(getSpecifierForModuleSymbol(target.parent!, context)) + // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned + // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag + // In such cases, the `target` refers to the module itself already + createLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) ), ModifierFlags.None); break; case SyntaxKind.NamespaceImport: @@ -5614,7 +5617,7 @@ namespace ts { createIdentifier(localName) ) ])), - createLiteral(getSpecifierForModuleSymbol(target.parent!, context)) + createLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) ), ModifierFlags.None); break; case SyntaxKind.ExportSpecifier: diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 1c6bd16e1baeb..7746ad00b430e 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -285,6 +285,7 @@ namespace ts { let combinedStatements: NodeArray; if (isSourceFileJS(currentSourceFile)) { combinedStatements = createNodeArray(transformDeclarationsForJS(node)); + refs.forEach(referenceVisitor); emittedImports = filter(combinedStatements, isAnyImportSyntax); } else { diff --git a/tests/baselines/reference/jsDeclarationsFunctions.js b/tests/baselines/reference/jsDeclarationsFunctions.js index c80fe43a1d2d4..23f300e2a1469 100644 --- a/tests/baselines/reference/jsDeclarationsFunctions.js +++ b/tests/baselines/reference/jsDeclarationsFunctions.js @@ -130,8 +130,6 @@ export namespace b { export function c(): void; export namespace c { export { Cls }; - class Cls { - } } /** * @param {number} a @@ -156,6 +154,8 @@ export namespace f { } export function i(): void; export function j(): void; +declare class Cls { +} /** * @param {{x: string}} a * @param {{y: typeof b}} b diff --git a/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js new file mode 100644 index 0000000000000..f35fad8297bbd --- /dev/null +++ b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js @@ -0,0 +1,43 @@ +//// [jsxDeclarationsWithEsModuleInteropNoCrash.jsx] +/// +import PropTypes from 'prop-types'; +import React from 'react'; + +const propTypes = { + bar: PropTypes.bool, +}; + +const defaultProps = { + bar: false, +}; + +function Foo({ bar }) { + return
{bar}
; +} + +Foo.propTypes = propTypes; +Foo.defaultProps = defaultProps; + +export default Foo; + + + +//// [jsxDeclarationsWithEsModuleInteropNoCrash.d.ts] +/// +export default Foo; +declare function Foo({ bar }: { + bar: any; +}): JSX.Element; +declare namespace Foo { + export { propTypes }; + export { defaultProps }; +} +declare namespace propTypes { + import bar = PropTypes.bool; + export { bar }; +} +declare namespace defaultProps { + const bar_1: boolean; + export { bar_1 as bar }; +} +import PropTypes from "prop-types"; diff --git a/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.symbols b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.symbols new file mode 100644 index 0000000000000..1efb61e125860 --- /dev/null +++ b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.symbols @@ -0,0 +1,52 @@ +=== tests/cases/compiler/jsxDeclarationsWithEsModuleInteropNoCrash.jsx === +/// +import PropTypes from 'prop-types'; +>PropTypes : Symbol(PropTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 1, 6)) + +import React from 'react'; +>React : Symbol(React, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 2, 6)) + +const propTypes = { +>propTypes : Symbol(propTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 4, 5)) + + bar: PropTypes.bool, +>bar : Symbol(bar, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 4, 19)) +>PropTypes.bool : Symbol(PropTypes.bool, Decl(react16.d.ts, 62, 16)) +>PropTypes : Symbol(PropTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 1, 6)) +>bool : Symbol(PropTypes.bool, Decl(react16.d.ts, 62, 16)) + +}; + +const defaultProps = { +>defaultProps : Symbol(defaultProps, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 8, 5)) + + bar: false, +>bar : Symbol(bar, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 8, 22)) + +}; + +function Foo({ bar }) { +>Foo : Symbol(Foo, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 10, 2), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) +>bar : Symbol(bar, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 12, 14)) + + return
{bar}
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>bar : Symbol(bar, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 12, 14)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +} + +Foo.propTypes = propTypes; +>Foo.propTypes : Symbol(Foo.propTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1)) +>Foo : Symbol(Foo, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 10, 2), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) +>propTypes : Symbol(Foo.propTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1)) +>propTypes : Symbol(propTypes, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 4, 5)) + +Foo.defaultProps = defaultProps; +>Foo.defaultProps : Symbol(Foo.defaultProps, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) +>Foo : Symbol(Foo, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 10, 2), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) +>defaultProps : Symbol(Foo.defaultProps, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) +>defaultProps : Symbol(defaultProps, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 8, 5)) + +export default Foo; +>Foo : Symbol(Foo, Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 10, 2), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 14, 1), Decl(jsxDeclarationsWithEsModuleInteropNoCrash.jsx, 16, 26)) + diff --git a/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.types b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.types new file mode 100644 index 0000000000000..25a0261778435 --- /dev/null +++ b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.types @@ -0,0 +1,58 @@ +=== tests/cases/compiler/jsxDeclarationsWithEsModuleInteropNoCrash.jsx === +/// +import PropTypes from 'prop-types'; +>PropTypes : typeof PropTypes + +import React from 'react'; +>React : typeof React + +const propTypes = { +>propTypes : { bar: PropTypes.Requireable; } +>{ bar: PropTypes.bool,} : { bar: PropTypes.Requireable; } + + bar: PropTypes.bool, +>bar : PropTypes.Requireable +>PropTypes.bool : PropTypes.Requireable +>PropTypes : typeof PropTypes +>bool : PropTypes.Requireable + +}; + +const defaultProps = { +>defaultProps : { bar: boolean; } +>{ bar: false,} : { bar: boolean; } + + bar: false, +>bar : boolean +>false : false + +}; + +function Foo({ bar }) { +>Foo : typeof Foo +>bar : any + + return
{bar}
; +>
{bar}
: JSX.Element +>div : any +>bar : any +>div : any +} + +Foo.propTypes = propTypes; +>Foo.propTypes = propTypes : { bar: PropTypes.Requireable; } +>Foo.propTypes : { bar: PropTypes.Requireable; } +>Foo : typeof Foo +>propTypes : { bar: PropTypes.Requireable; } +>propTypes : { bar: PropTypes.Requireable; } + +Foo.defaultProps = defaultProps; +>Foo.defaultProps = defaultProps : { bar: boolean; } +>Foo.defaultProps : { bar: boolean; } +>Foo : typeof Foo +>defaultProps : { bar: boolean; } +>defaultProps : { bar: boolean; } + +export default Foo; +>Foo : typeof Foo + diff --git a/tests/cases/compiler/jsxDeclarationsWithEsModuleInteropNoCrash.tsx b/tests/cases/compiler/jsxDeclarationsWithEsModuleInteropNoCrash.tsx new file mode 100644 index 0000000000000..4c74c67fb3a7a --- /dev/null +++ b/tests/cases/compiler/jsxDeclarationsWithEsModuleInteropNoCrash.tsx @@ -0,0 +1,29 @@ +// @allowJs: true +// @checkJs: true +// @emitDeclarationOnly: true +// @declaration: true +// @strict: true +// @esModuleInterop: true +// @jsx: react +// @noImplicitAny: false +// @filename: jsxDeclarationsWithEsModuleInteropNoCrash.jsx +/// +import PropTypes from 'prop-types'; +import React from 'react'; + +const propTypes = { + bar: PropTypes.bool, +}; + +const defaultProps = { + bar: false, +}; + +function Foo({ bar }) { + return
{bar}
; +} + +Foo.propTypes = propTypes; +Foo.defaultProps = defaultProps; + +export default Foo; \ No newline at end of file