diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8797dbbf80137..6d77fc7c3804f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31536,13 +31536,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isPossiblyAliasedThisProperty(binaryExpression, kind)) { return getContextualTypeForThisPropertyAssignment(binaryExpression); } + let nodeSymbol; + if (canHaveSymbol(binaryExpression.left)) { + nodeSymbol = binaryExpression.left.symbol; + if (!nodeSymbol) { + const resolvedSymbol = getNodeLinks(binaryExpression.left).resolvedSymbol; + if (resolvedSymbol && getIsLateCheckFlag(resolvedSymbol)) { + nodeSymbol = resolvedSymbol; + } + } + } // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration. // See `bindStaticPropertyAssignment` in `binder.ts`. - else if (!canHaveSymbol(binaryExpression.left) || !binaryExpression.left.symbol) { + if (!nodeSymbol) { return getTypeOfExpression(binaryExpression.left); } else { - const decl = binaryExpression.left.symbol.valueDeclaration; + const decl = nodeSymbol.valueDeclaration; if (!decl) { return undefined; } @@ -31565,6 +31575,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } } + Debug.assert(canHaveSymbol(binaryExpression.left)); return isInJSFile(decl) || decl === binaryExpression.left ? undefined : getTypeOfExpression(binaryExpression.left); } case AssignmentDeclarationKind.ExportsProperty: diff --git a/tests/baselines/reference/uniqueSymbolExpando1.symbols b/tests/baselines/reference/uniqueSymbolExpando1.symbols new file mode 100644 index 0000000000000..43d7979e0cb98 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolExpando1.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/uniqueSymbolExpando1.ts] //// + +=== uniqueSymbolExpando1.ts === +// https://github.com/microsoft/TypeScript/issues/61214 + +const TestSymbol: unique symbol = Symbol(); +>TestSymbol : Symbol(TestSymbol, Decl(uniqueSymbolExpando1.ts, 2, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +const c = () => { +>c : Symbol(c, Decl(uniqueSymbolExpando1.ts, 4, 5), Decl(uniqueSymbolExpando1.ts, 6, 2), Decl(uniqueSymbolExpando1.ts, 7, 26)) + + return "Hello, world!"; +}; +c["testProp"] = ["Hello"]; +>c : Symbol(c, Decl(uniqueSymbolExpando1.ts, 4, 5), Decl(uniqueSymbolExpando1.ts, 6, 2), Decl(uniqueSymbolExpando1.ts, 7, 26)) +>"testProp" : Symbol(c["testProp"], Decl(uniqueSymbolExpando1.ts, 6, 2)) + +c[TestSymbol] = ["Hello"]; +>c : Symbol(c, Decl(uniqueSymbolExpando1.ts, 4, 5), Decl(uniqueSymbolExpando1.ts, 6, 2), Decl(uniqueSymbolExpando1.ts, 7, 26)) +>TestSymbol : Symbol(TestSymbol, Decl(uniqueSymbolExpando1.ts, 2, 5)) + diff --git a/tests/baselines/reference/uniqueSymbolExpando1.types b/tests/baselines/reference/uniqueSymbolExpando1.types new file mode 100644 index 0000000000000..408fc8b34a51c --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolExpando1.types @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/uniqueSymbolExpando1.ts] //// + +=== uniqueSymbolExpando1.ts === +// https://github.com/microsoft/TypeScript/issues/61214 + +const TestSymbol: unique symbol = Symbol(); +>TestSymbol : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol() : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ + +const c = () => { +>c : { (): string; testProp: string[]; [TestSymbol]: string[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>() => { return "Hello, world!";} : { (): string; testProp: string[]; [TestSymbol]: string[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + return "Hello, world!"; +>"Hello, world!" : "Hello, world!" +> : ^^^^^^^^^^^^^^^ + +}; +c["testProp"] = ["Hello"]; +>c["testProp"] = ["Hello"] : string[] +> : ^^^^^^^^ +>c["testProp"] : string[] +> : ^^^^^^^^ +>c : { (): string; testProp: string[]; [TestSymbol]: string[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"testProp" : "testProp" +> : ^^^^^^^^^^ +>["Hello"] : string[] +> : ^^^^^^^^ +>"Hello" : "Hello" +> : ^^^^^^^ + +c[TestSymbol] = ["Hello"]; +>c[TestSymbol] = ["Hello"] : string[] +> : ^^^^^^^^ +>c[TestSymbol] : string[] +> : ^^^^^^^^ +>c : { (): string; testProp: string[]; [TestSymbol]: string[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>TestSymbol : unique symbol +> : ^^^^^^^^^^^^^ +>["Hello"] : string[] +> : ^^^^^^^^ +>"Hello" : "Hello" +> : ^^^^^^^ + diff --git a/tests/baselines/reference/wellKnownSymbolExpando.types b/tests/baselines/reference/wellKnownSymbolExpando.types index d8015edeebaf6..e587d4eeb6dfe 100644 --- a/tests/baselines/reference/wellKnownSymbolExpando.types +++ b/tests/baselines/reference/wellKnownSymbolExpando.types @@ -8,7 +8,8 @@ function f() {} f[Symbol.iterator] = function() {} >f[Symbol.iterator] = function() {} : () => void > : ^^^^^^^^^^ ->f[Symbol.iterator] : any +>f[Symbol.iterator] : () => void +> : ^^^^^^^^^^ >f : typeof f > : ^^^^^^^^ >Symbol.iterator : unique symbol diff --git a/tests/cases/compiler/uniqueSymbolExpando1.ts b/tests/cases/compiler/uniqueSymbolExpando1.ts new file mode 100644 index 0000000000000..1bbac7be1a773 --- /dev/null +++ b/tests/cases/compiler/uniqueSymbolExpando1.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/61214 + +const TestSymbol: unique symbol = Symbol(); + +const c = () => { + return "Hello, world!"; +}; +c["testProp"] = ["Hello"]; +c[TestSymbol] = ["Hello"]; diff --git a/tests/cases/compiler/wellKnownSymbolExpando.ts b/tests/cases/compiler/wellKnownSymbolExpando.ts index b80fa2bb8b28d..14defcd316dc7 100644 --- a/tests/cases/compiler/wellKnownSymbolExpando.ts +++ b/tests/cases/compiler/wellKnownSymbolExpando.ts @@ -1,3 +1,4 @@ +// @strict: true // @noEmit: true // @target: esnext