diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee86ae50306c7..78acaad7d2011 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11055,8 +11055,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { reportErrorsFromWidening(declaration, type); } - // always widen a 'unique symbol' type if the type was created for a different declaration. - if (type.flags & TypeFlags.UniqueESSymbol && (isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfDeclaration(declaration)) { + // always widen a 'unique symbol' type if the type was created for a different declaration and if it isn't accessible + if (type.flags & TypeFlags.UniqueESSymbol && !declaration.type && type.symbol !== getSymbolOfDeclaration(declaration) && !isValueSymbolAccessible(type.symbol, type.symbol.valueDeclaration)) { type = esSymbolType; } @@ -37570,7 +37570,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function widenTypeInferredFromInitializer(declaration: HasExpressionInitializer, type: Type) { - const widened = getCombinedNodeFlagsCached(declaration) & NodeFlags.Constant || isDeclarationReadonly(declaration) ? type : getWidenedLiteralType(type); + const widened = getCombinedNodeFlagsCached(declaration) & NodeFlags.Constant || isDeclarationReadonly(declaration) ? type : getWidenedUniqueESSymbolType(getWidenedLiteralType(type)); if (isInJSFile(declaration)) { if (isEmptyLiteralType(widened)) { reportImplicitAny(declaration, anyType); diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.js b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.js new file mode 100644 index 0000000000000..ade471c432477 --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.js @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts] //// + +//// [indirectUniqueSymbolDeclarationEmit2.ts] +// repro from https://github.com/microsoft/TypeScript/issues/53276 + +export const a = Symbol.toStringTag; + +export class F { + [a](){ return "" } +} + +export const b = (new F())[a]; + + +//// [indirectUniqueSymbolDeclarationEmit2.js] +"use strict"; +// repro from https://github.com/microsoft/TypeScript/issues/53276 +Object.defineProperty(exports, "__esModule", { value: true }); +exports.b = exports.F = exports.a = void 0; +exports.a = Symbol.toStringTag; +var F = /** @class */ (function () { + function F() { + } + F.prototype[exports.a] = function () { return ""; }; + return F; +}()); +exports.F = F; +exports.b = (new F())[exports.a]; + + +//// [indirectUniqueSymbolDeclarationEmit2.d.ts] +export declare const a: typeof Symbol.toStringTag; +export declare class F { + [a](): string; +} +export declare const b: () => string; diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.symbols b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.symbols new file mode 100644 index 0000000000000..aafb4036487f4 --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.symbols @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts] //// + +=== indirectUniqueSymbolDeclarationEmit2.ts === +// repro from https://github.com/microsoft/TypeScript/issues/53276 + +export const a = Symbol.toStringTag; +>a : Symbol(a, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 2, 12)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>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, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export class F { +>F : Symbol(F, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 2, 36)) + + [a](){ return "" } +>[a] : Symbol(F[a], Decl(indirectUniqueSymbolDeclarationEmit2.ts, 4, 16)) +>a : Symbol(a, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 2, 12)) +} + +export const b = (new F())[a]; +>b : Symbol(b, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 8, 12)) +>F : Symbol(F, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 2, 36)) +>a : Symbol(a, Decl(indirectUniqueSymbolDeclarationEmit2.ts, 2, 12)) + diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.types b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.types new file mode 100644 index 0000000000000..896a01c36c2b3 --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit2.types @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts] //// + +=== indirectUniqueSymbolDeclarationEmit2.ts === +// repro from https://github.com/microsoft/TypeScript/issues/53276 + +export const a = Symbol.toStringTag; +>a : unique symbol +>Symbol.toStringTag : unique symbol +>Symbol : SymbolConstructor +>toStringTag : unique symbol + +export class F { +>F : F + + [a](){ return "" } +>[a] : () => string +>a : unique symbol +>"" : "" +} + +export const b = (new F())[a]; +>b : () => string +>(new F())[a] : () => string +>(new F()) : F +>new F() : F +>F : typeof F +>a : unique symbol + diff --git a/tests/baselines/reference/uniqueSymbols.types b/tests/baselines/reference/uniqueSymbols.types index 37e1d29fcc38f..f5611658f4470 100644 --- a/tests/baselines/reference/uniqueSymbols.types +++ b/tests/baselines/reference/uniqueSymbols.types @@ -29,7 +29,7 @@ const constTypeAndCall: unique symbol = Symbol(); // declaration from initializer const constInitToConstCall = constCall; ->constInitToConstCall : symbol +>constInitToConstCall : unique symbol >constCall : unique symbol const constInitToLetCall = letCall; @@ -41,7 +41,7 @@ const constInitToVarCall = varCall; >varCall : symbol const constInitToConstDeclAmbient = constType; ->constInitToConstDeclAmbient : symbol +>constInitToConstDeclAmbient : unique symbol >constType : unique symbol let letInitToConstCall = constCall; @@ -201,19 +201,19 @@ declare const c: C; >c : C const constInitToCReadonlyStaticCall = C.readonlyStaticCall; ->constInitToCReadonlyStaticCall : symbol +>constInitToCReadonlyStaticCall : unique symbol >C.readonlyStaticCall : unique symbol >C : typeof C >readonlyStaticCall : unique symbol const constInitToCReadonlyStaticType = C.readonlyStaticType; ->constInitToCReadonlyStaticType : symbol +>constInitToCReadonlyStaticType : unique symbol >C.readonlyStaticType : unique symbol >C : typeof C >readonlyStaticType : unique symbol const constInitToCReadonlyStaticTypeAndCall = C.readonlyStaticTypeAndCall; ->constInitToCReadonlyStaticTypeAndCall : symbol +>constInitToCReadonlyStaticTypeAndCall : unique symbol >C.readonlyStaticTypeAndCall : unique symbol >C : typeof C >readonlyStaticTypeAndCall : unique symbol @@ -311,7 +311,7 @@ declare const i: I; >i : I const constInitToIReadonlyType = i.readonlyType; ->constInitToIReadonlyType : symbol +>constInitToIReadonlyType : unique symbol >i.readonlyType : unique symbol >i : I >readonlyType : unique symbol @@ -536,17 +536,17 @@ class C0 { >C0 : C0 static readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol static readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol static readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" @@ -568,17 +568,17 @@ class C0 { >"s" : "s" readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.js b/tests/baselines/reference/uniqueSymbolsDeclarations.js index 01d07f1d9f1d5..6d2e7229e6056 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.js +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.js @@ -414,10 +414,10 @@ declare let letCall: symbol; declare var varCall: symbol; declare const constType: unique symbol; declare const constTypeAndCall: unique symbol; -declare const constInitToConstCall: symbol; +declare const constInitToConstCall: typeof constCall; declare const constInitToLetCall: symbol; declare const constInitToVarCall: symbol; -declare const constInitToConstDeclAmbient: symbol; +declare const constInitToConstDeclAmbient: typeof constType; declare let letInitToConstCall: symbol; declare let letInitToLetCall: symbol; declare let letInitToVarCall: symbol; @@ -451,9 +451,9 @@ declare class C { readwriteCall: symbol; } declare const c: C; -declare const constInitToCReadonlyStaticCall: symbol; -declare const constInitToCReadonlyStaticType: symbol; -declare const constInitToCReadonlyStaticTypeAndCall: symbol; +declare const constInitToCReadonlyStaticCall: typeof C.readonlyStaticCall; +declare const constInitToCReadonlyStaticType: typeof C.readonlyStaticType; +declare const constInitToCReadonlyStaticTypeAndCall: typeof C.readonlyStaticTypeAndCall; declare const constInitToCReadwriteStaticCall: symbol; declare const constInitToCReadonlyStaticCallWithTypeQuery: typeof C.readonlyStaticCall; declare const constInitToCReadonlyStaticTypeWithTypeQuery: typeof C.readonlyStaticType; @@ -469,7 +469,7 @@ interface I { readonly readonlyType: unique symbol; } declare const i: I; -declare const constInitToIReadonlyType: symbol; +declare const constInitToIReadonlyType: typeof i.readonlyType; declare const constInitToIReadonlyTypeWithTypeQuery: typeof i.readonlyType; declare const constInitToIReadonlyTypeWithIndexedAccess: I["readonlyType"]; type L = { @@ -509,15 +509,15 @@ declare const o2: { method5(p?: symbol): symbol; }; declare class C0 { - static readonly a: symbol; - static readonly b: symbol; - static readonly c: symbol; + static readonly a: typeof s; + static readonly b: typeof N.s; + static readonly c: typeof N.s; static d: symbol; static e: symbol; static f: symbol; - readonly a: symbol; - readonly b: symbol; - readonly c: symbol; + readonly a: typeof s; + readonly b: typeof N.s; + readonly c: typeof N.s; d: symbol; e: symbol; f: symbol; diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.types b/tests/baselines/reference/uniqueSymbolsDeclarations.types index b22c81175916e..9abca24e2a3b1 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.types +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.types @@ -29,7 +29,7 @@ const constTypeAndCall: unique symbol = Symbol(); // declaration from initializer const constInitToConstCall = constCall; ->constInitToConstCall : symbol +>constInitToConstCall : unique symbol >constCall : unique symbol const constInitToLetCall = letCall; @@ -41,7 +41,7 @@ const constInitToVarCall = varCall; >varCall : symbol const constInitToConstDeclAmbient = constType; ->constInitToConstDeclAmbient : symbol +>constInitToConstDeclAmbient : unique symbol >constType : unique symbol let letInitToConstCall = constCall; @@ -194,19 +194,19 @@ declare const c: C; >c : C const constInitToCReadonlyStaticCall = C.readonlyStaticCall; ->constInitToCReadonlyStaticCall : symbol +>constInitToCReadonlyStaticCall : unique symbol >C.readonlyStaticCall : unique symbol >C : typeof C >readonlyStaticCall : unique symbol const constInitToCReadonlyStaticType = C.readonlyStaticType; ->constInitToCReadonlyStaticType : symbol +>constInitToCReadonlyStaticType : unique symbol >C.readonlyStaticType : unique symbol >C : typeof C >readonlyStaticType : unique symbol const constInitToCReadonlyStaticTypeAndCall = C.readonlyStaticTypeAndCall; ->constInitToCReadonlyStaticTypeAndCall : symbol +>constInitToCReadonlyStaticTypeAndCall : unique symbol >C.readonlyStaticTypeAndCall : unique symbol >C : typeof C >readonlyStaticTypeAndCall : unique symbol @@ -304,7 +304,7 @@ declare const i: I; >i : I const constInitToIReadonlyType = i.readonlyType; ->constInitToIReadonlyType : symbol +>constInitToIReadonlyType : unique symbol >i.readonlyType : unique symbol >i : I >readonlyType : unique symbol @@ -529,17 +529,17 @@ class C0 { >C0 : C0 static readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol static readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol static readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" @@ -561,17 +561,17 @@ class C0 { >"s" : "s" readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" diff --git a/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts b/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts new file mode 100644 index 0000000000000..ba8abf37f0ec6 --- /dev/null +++ b/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit2.ts @@ -0,0 +1,13 @@ +// @strict: true +// @lib: esnext +// @declaration: true + +// repro from https://github.com/microsoft/TypeScript/issues/53276 + +export const a = Symbol.toStringTag; + +export class F { + [a](){ return "" } +} + +export const b = (new F())[a];