diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b26af72dcc4..6ea9b826954 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3309,7 +3309,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { function bindSpecialPropertyAssignment(node: BindablePropertyAssignmentExpression) { // Class declarations in Typescript do not allow property declarations - const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression, container) || lookupSymbolForPropertyAccess(node.left.expression, blockScopeContainer); + const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression, blockScopeContainer) || lookupSymbolForPropertyAccess(node.left.expression, container); if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) { return; } @@ -3428,7 +3428,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } function bindPropertyAssignment(name: BindableStaticNameExpression, propertyAccess: BindableStaticAccessExpression, isPrototypeProperty: boolean, containerIsClass: boolean) { - let namespaceSymbol = lookupSymbolForPropertyAccess(name, container) || lookupSymbolForPropertyAccess(name, blockScopeContainer); + let namespaceSymbol = lookupSymbolForPropertyAccess(name, blockScopeContainer) || lookupSymbolForPropertyAccess(name, container); const isToplevel = isTopLevelNamespaceAssignment(propertyAccess); namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass); bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty); diff --git a/tests/baselines/reference/expandoFunctionBlockShadowing.js b/tests/baselines/reference/expandoFunctionBlockShadowing.js new file mode 100644 index 00000000000..5937115a058 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionBlockShadowing.js @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/expandoFunctionBlockShadowing.ts] //// + +//// [expandoFunctionBlockShadowing.ts] +// https://github.com/microsoft/TypeScript/issues/56538 + +export function X() {} +if (Math.random()) { + const X: { test?: any } = {}; + X.test = 1; +} + +export function Y() {} +Y.test = "foo"; +const aliasTopY = Y; +if (Math.random()) { + const Y = function Y() {} + Y.test = 42; + + const topYcheck: { (): void; test: string } = aliasTopY; + const blockYcheck: { (): void; test: number } = Y; +} + +//// [expandoFunctionBlockShadowing.js] +"use strict"; +// https://github.com/microsoft/TypeScript/issues/56538 +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Y = exports.X = void 0; +function X() { } +exports.X = X; +if (Math.random()) { + var X_1 = {}; + X_1.test = 1; +} +function Y() { } +exports.Y = Y; +Y.test = "foo"; +var aliasTopY = Y; +if (Math.random()) { + var Y_1 = function Y() { }; + Y_1.test = 42; + var topYcheck = aliasTopY; + var blockYcheck = Y_1; +} + + +//// [expandoFunctionBlockShadowing.d.ts] +export declare function X(): void; +export declare function Y(): void; +export declare namespace Y { + var test: string; +} diff --git a/tests/baselines/reference/expandoFunctionBlockShadowing.symbols b/tests/baselines/reference/expandoFunctionBlockShadowing.symbols new file mode 100644 index 00000000000..d4e7f017fbc --- /dev/null +++ b/tests/baselines/reference/expandoFunctionBlockShadowing.symbols @@ -0,0 +1,59 @@ +//// [tests/cases/compiler/expandoFunctionBlockShadowing.ts] //// + +=== expandoFunctionBlockShadowing.ts === +// https://github.com/microsoft/TypeScript/issues/56538 + +export function X() {} +>X : Symbol(X, Decl(expandoFunctionBlockShadowing.ts, 0, 0)) + +if (Math.random()) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + const X: { test?: any } = {}; +>X : Symbol(X, Decl(expandoFunctionBlockShadowing.ts, 4, 7)) +>test : Symbol(test, Decl(expandoFunctionBlockShadowing.ts, 4, 12)) + + X.test = 1; +>X.test : Symbol(test, Decl(expandoFunctionBlockShadowing.ts, 4, 12)) +>X : Symbol(X, Decl(expandoFunctionBlockShadowing.ts, 4, 7)) +>test : Symbol(test, Decl(expandoFunctionBlockShadowing.ts, 4, 12)) +} + +export function Y() {} +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 6, 1), Decl(expandoFunctionBlockShadowing.ts, 8, 22)) + +Y.test = "foo"; +>Y.test : Symbol(Y.test, Decl(expandoFunctionBlockShadowing.ts, 8, 22)) +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 6, 1), Decl(expandoFunctionBlockShadowing.ts, 8, 22)) +>test : Symbol(Y.test, Decl(expandoFunctionBlockShadowing.ts, 8, 22)) + +const aliasTopY = Y; +>aliasTopY : Symbol(aliasTopY, Decl(expandoFunctionBlockShadowing.ts, 10, 5)) +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 6, 1), Decl(expandoFunctionBlockShadowing.ts, 8, 22)) + +if (Math.random()) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + const Y = function Y() {} +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 12, 7)) +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 12, 11)) + + Y.test = 42; +>Y.test : Symbol(Y.test, Decl(expandoFunctionBlockShadowing.ts, 12, 27)) +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 12, 7)) +>test : Symbol(Y.test, Decl(expandoFunctionBlockShadowing.ts, 12, 27)) + + const topYcheck: { (): void; test: string } = aliasTopY; +>topYcheck : Symbol(topYcheck, Decl(expandoFunctionBlockShadowing.ts, 15, 7)) +>test : Symbol(test, Decl(expandoFunctionBlockShadowing.ts, 15, 30)) +>aliasTopY : Symbol(aliasTopY, Decl(expandoFunctionBlockShadowing.ts, 10, 5)) + + const blockYcheck: { (): void; test: number } = Y; +>blockYcheck : Symbol(blockYcheck, Decl(expandoFunctionBlockShadowing.ts, 16, 7)) +>test : Symbol(test, Decl(expandoFunctionBlockShadowing.ts, 16, 32)) +>Y : Symbol(Y, Decl(expandoFunctionBlockShadowing.ts, 12, 7)) +} diff --git a/tests/baselines/reference/expandoFunctionBlockShadowing.types b/tests/baselines/reference/expandoFunctionBlockShadowing.types new file mode 100644 index 00000000000..b57e82c412e --- /dev/null +++ b/tests/baselines/reference/expandoFunctionBlockShadowing.types @@ -0,0 +1,69 @@ +//// [tests/cases/compiler/expandoFunctionBlockShadowing.ts] //// + +=== expandoFunctionBlockShadowing.ts === +// https://github.com/microsoft/TypeScript/issues/56538 + +export function X() {} +>X : () => void + +if (Math.random()) { +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number + + const X: { test?: any } = {}; +>X : { test?: any; } +>test : any +>{} : {} + + X.test = 1; +>X.test = 1 : 1 +>X.test : any +>X : { test?: any; } +>test : any +>1 : 1 +} + +export function Y() {} +>Y : typeof Y + +Y.test = "foo"; +>Y.test = "foo" : "foo" +>Y.test : string +>Y : typeof Y +>test : string +>"foo" : "foo" + +const aliasTopY = Y; +>aliasTopY : typeof Y +>Y : typeof Y + +if (Math.random()) { +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number + + const Y = function Y() {} +>Y : { (): void; test: number; } +>function Y() {} : { (): void; test: number; } +>Y : { (): void; test: number; } + + Y.test = 42; +>Y.test = 42 : 42 +>Y.test : number +>Y : { (): void; test: number; } +>test : number +>42 : 42 + + const topYcheck: { (): void; test: string } = aliasTopY; +>topYcheck : { (): void; test: string; } +>test : string +>aliasTopY : typeof import("expandoFunctionBlockShadowing").Y + + const blockYcheck: { (): void; test: number } = Y; +>blockYcheck : { (): void; test: number; } +>test : number +>Y : { (): void; test: number; } +} diff --git a/tests/cases/compiler/expandoFunctionBlockShadowing.ts b/tests/cases/compiler/expandoFunctionBlockShadowing.ts new file mode 100644 index 00000000000..e55499a33de --- /dev/null +++ b/tests/cases/compiler/expandoFunctionBlockShadowing.ts @@ -0,0 +1,21 @@ +// @strict: true +// @declaration: true + +// https://github.com/microsoft/TypeScript/issues/56538 + +export function X() {} +if (Math.random()) { + const X: { test?: any } = {}; + X.test = 1; +} + +export function Y() {} +Y.test = "foo"; +const aliasTopY = Y; +if (Math.random()) { + const Y = function Y() {} + Y.test = 42; + + const topYcheck: { (): void; test: string } = aliasTopY; + const blockYcheck: { (): void; test: number } = Y; +} \ No newline at end of file