From 422bdb02769e3ef18e4cf97118838690f33549ec Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 2 Sep 2025 14:27:32 +0530 Subject: [PATCH 01/11] Fix unique symbol .d.ts generation and add baseline test --- src/compiler/emitter.ts | 55 ++++-- src/compiler/transformers/declarations.ts | 26 ++- tests/baselines/reference/api/typescript.d.ts | 3 +- .../uniqueSymbolReassignment.errors.txt | 48 +++++ .../reference/uniqueSymbolReassignment.js | 65 +++++++ .../uniqueSymbolReassignment.symbols | 90 +++++++++ .../reference/uniqueSymbolReassignment.types | 176 ++++++++++++++++++ .../compiler/uniqueSymbolReassignment.ts | 34 ++++ 8 files changed, 483 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.errors.txt create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.js create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.symbols create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.types create mode 100644 tests/cases/compiler/uniqueSymbolReassignment.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c60fd92787275..c8834ee680c4e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -423,15 +423,41 @@ import { WriteFileCallbackData, YieldExpression, } from "./_namespaces/ts.js"; +import { isTypeReferenceNode, TypeFlags, TypeChecker } from "./_namespaces/ts.js"; import * as performance from "./_namespaces/ts.performance.js"; - const brackets = createBracketsMap(); + + /** @internal */ +export function isUniqueSymbolDeclaration(node: VariableDeclarationList, checker: TypeChecker): boolean { + return node.declarations.some((decl: VariableDeclaration) => { + // 1. If type is explicitly written, handle as before + const typeNode: TypeNode | undefined = decl.type; + if (typeNode) { + if (isTypeReferenceNode(typeNode) && isIdentifier(typeNode.typeName)) { + if (typeNode.typeName.escapedText.toString() === "unique symbol") { + return true; + } + } + if ((typeNode.kind as SyntaxKind) === SyntaxKind.UniqueKeyword) { + return true; + } + } + // 2. Otherwise, check the inferred type + const type = checker.getTypeAtLocation(decl.name); + if (type.flags & TypeFlags.UniqueESSymbol) { + return true; + } + + return false; + }); +} + export function isBuildInfoFile(file: string): boolean { return fileExtensionIs(file, Extension.TsBuildInfo); } - + /** * Iterates over the source files that are expected to have an emit output. * @@ -741,6 +767,7 @@ export function emitFiles( onlyBuildInfo: boolean, forceDtsEmit?: boolean, skipBuildInfo?: boolean, + emitTypeChecker?: TypeChecker, ): EmitResult { // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 @@ -841,7 +868,7 @@ export function emitFiles( extendedDiagnostics: compilerOptions.extendedDiagnostics, }; - // Create a printer to print the nodes + const typeChecker = emitTypeChecker; const printer = createPrinter(printerOptions, { // resolver hooks hasGlobalName: resolver.hasGlobalName, @@ -850,12 +877,11 @@ export function emitFiles( onEmitNode: transform.emitNodeWithNotification, isEmitNotificationEnabled: transform.isEmitNotificationEnabled, substituteNode: transform.substituteNode, - }); + }, typeChecker); Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform"); printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform, printer, compilerOptions); - // Clean up emit nodes on parse tree transform.dispose(); if (emittedFilesList) { @@ -900,6 +926,8 @@ export function emitFiles( } } + // TypeChecker is already captured in the closure above + const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit; emitSkipped = emitSkipped || declBlocked; if (!declBlocked || forceDtsEmit) { @@ -1191,7 +1219,7 @@ export const createPrinterWithRemoveCommentsNeverAsciiEscape: () => Printer = /* /** @internal */ export const createPrinterWithRemoveCommentsOmitTrailingSemicolon: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true })); -export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { +export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}, typeChecker?: TypeChecker): Printer { // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 /* eslint-disable no-var */ @@ -3343,7 +3371,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeSpace(); emit(node.caseBlock); } - function emitLabeledStatement(node: LabeledStatement) { emit(node.label); emitTokenWithComment(SyntaxKind.ColonToken, node.label.end, writePunctuation, node); @@ -3394,18 +3421,24 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeKeyword("await"); writeSpace(); writeKeyword("using"); - } - else { - const head = isLet(node) ? "let" : + } else { + // Check if unique symbol and use const instead of var + const isUnique = typeChecker && isUniqueSymbolDeclaration(node, typeChecker); + const head = + isLet(node) ? "let" : isVarConst(node) ? "const" : isVarUsing(node) ? "using" : + isUnique ? "const" : "var"; + writeKeyword(head); } - writeSpace(); + + writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } + function emitFunctionDeclaration(node: FunctionDeclaration) { emitFunctionDeclarationOrExpression(node); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 4b6941dc61f95..370d7c889f73e 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -111,6 +111,7 @@ import { isFunctionDeclaration, isFunctionLike, isGlobalScopeAugmentation, + isIdentifier, isIdentifierText, isImportEqualsDeclaration, isIndexSignatureDeclaration, @@ -140,6 +141,7 @@ import { isStringLiteralLike, isTupleTypeNode, isTypeAliasDeclaration, + isTypeReferenceNode, isTypeElement, isTypeLiteralNode, isTypeNode, @@ -217,6 +219,18 @@ import { VisitResult, } from "../_namespaces/ts.js"; + +function isUniqueSymbolByType(type: TypeNode | undefined): boolean { + if (!type) return false; + + if (type.kind === SyntaxKind.TypeOperator && (type as any).operator === SyntaxKind.UniqueKeyword) return true; + + if (isTypeReferenceNode(type) && isIdentifier(type.typeName)) { + if (type.typeName.escapedText === "unique symbol") return true; + } + return false; +} + /** @internal */ export function getDeclarationDiagnostics( host: EmitHost, @@ -1479,7 +1493,15 @@ export function transformDeclarations(context: TransformationContext): Transform exportMappings.push([name, nameStr]); } const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); - return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl])); + const shouldForceConst = isUniqueSymbolByType(type); + + const declList = factory.createVariableDeclarationList( + [varDecl], + shouldForceConst ? NodeFlags.Const : NodeFlags.None + ); + + return factory.createVariableStatement( + isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)],declList); }); if (!exportMappings.length) { declarations = mapDefined(declarations, declaration => factory.replaceModifiers(declaration, ModifierFlags.None)); @@ -1971,4 +1993,4 @@ function isProcessedComponent(node: Node): node is ProcessedComponent { return true; } return false; -} +} \ No newline at end of file diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 943ff5e152290..20dcd74f31b9b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -9499,9 +9499,10 @@ declare namespace ts { * @param context A lexical environment context for the visitor. */ function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext | undefined, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + function isBuildInfoFile(file: string): boolean; function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; - function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer; + function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers, typeChecker?: TypeChecker): Printer; enum ProgramUpdateLevel { /** Program is updated with same root file names and options */ Update = 0, diff --git a/tests/baselines/reference/uniqueSymbolReassignment.errors.txt b/tests/baselines/reference/uniqueSymbolReassignment.errors.txt new file mode 100644 index 0000000000000..9914be5cac584 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.errors.txt @@ -0,0 +1,48 @@ +uniqueSymbolReassignment.ts(2,18): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +uniqueSymbolReassignment.ts(7,23): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +uniqueSymbolReassignment.ts(19,26): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +uniqueSymbolReassignment.ts(20,26): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + + +==== uniqueSymbolReassignment.ts (4 errors) ==== + // This is a unique symbol (const + Symbol()) + const mySymbol = Symbol('Symbols.mySymbol'); + ~~~~~~ +!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + const Symbols = { + mySymbol + } as const; + + const anotherUnique = Symbol('symbols.anotherUnique'); + ~~~~~~ +!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + const Symbols2 = { + anotherUnique + } as const; + + function myFunction() {} + + // Attach the unique ones + myFunction.mySymbol = Symbols.mySymbol; + myFunction.anotherUnique = Symbols2.anotherUnique; + + // Non-unique symbols (regular Symbol() without const) + const nonUniqueSymbol1 = Symbol('nonUnique1'); + ~~~~~~ +!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + const nonUniqueSymbol2 = Symbol('nonUnique2'); + ~~~~~~ +!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + + // Plain text variables (not symbols at all) + const normalVar = "not a symbol"; + const symbolName = "this contains symbol but is not one"; + + // Attach those as well + myFunction.nonUnique1 = nonUniqueSymbol1; + myFunction.nonUnique2 = nonUniqueSymbol2; + myFunction.normalVar = normalVar; + myFunction.symbolName = symbolName; + + export { myFunction }; + \ No newline at end of file diff --git a/tests/baselines/reference/uniqueSymbolReassignment.js b/tests/baselines/reference/uniqueSymbolReassignment.js new file mode 100644 index 0000000000000..61318f7f9e92d --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.js @@ -0,0 +1,65 @@ +//// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// + +//// [uniqueSymbolReassignment.ts] +// This is a unique symbol (const + Symbol()) +const mySymbol = Symbol('Symbols.mySymbol'); +const Symbols = { + mySymbol +} as const; + +const anotherUnique = Symbol('symbols.anotherUnique'); +const Symbols2 = { + anotherUnique +} as const; + +function myFunction() {} + +// Attach the unique ones +myFunction.mySymbol = Symbols.mySymbol; +myFunction.anotherUnique = Symbols2.anotherUnique; + +// Non-unique symbols (regular Symbol() without const) +const nonUniqueSymbol1 = Symbol('nonUnique1'); +const nonUniqueSymbol2 = Symbol('nonUnique2'); + +// Plain text variables (not symbols at all) +const normalVar = "not a symbol"; +const symbolName = "this contains symbol but is not one"; + +// Attach those as well +myFunction.nonUnique1 = nonUniqueSymbol1; +myFunction.nonUnique2 = nonUniqueSymbol2; +myFunction.normalVar = normalVar; +myFunction.symbolName = symbolName; + +export { myFunction }; + + +//// [uniqueSymbolReassignment.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.myFunction = myFunction; +// This is a unique symbol (const + Symbol()) +var mySymbol = Symbol('Symbols.mySymbol'); +var Symbols = { + mySymbol: mySymbol +}; +var anotherUnique = Symbol('symbols.anotherUnique'); +var Symbols2 = { + anotherUnique: anotherUnique +}; +function myFunction() { } +// Attach the unique ones +myFunction.mySymbol = Symbols.mySymbol; +myFunction.anotherUnique = Symbols2.anotherUnique; +// Non-unique symbols (regular Symbol() without const) +var nonUniqueSymbol1 = Symbol('nonUnique1'); +var nonUniqueSymbol2 = Symbol('nonUnique2'); +// Plain text variables (not symbols at all) +var normalVar = "not a symbol"; +var symbolName = "this contains symbol but is not one"; +// Attach those as well +myFunction.nonUnique1 = nonUniqueSymbol1; +myFunction.nonUnique2 = nonUniqueSymbol2; +myFunction.normalVar = normalVar; +myFunction.symbolName = symbolName; diff --git a/tests/baselines/reference/uniqueSymbolReassignment.symbols b/tests/baselines/reference/uniqueSymbolReassignment.symbols new file mode 100644 index 0000000000000..740ae2dfb3b0f --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.symbols @@ -0,0 +1,90 @@ +//// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// + +=== uniqueSymbolReassignment.ts === +// This is a unique symbol (const + Symbol()) +const mySymbol = Symbol('Symbols.mySymbol'); +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 1, 5)) + +const Symbols = { +>Symbols : Symbol(Symbols, Decl(uniqueSymbolReassignment.ts, 2, 5)) + + mySymbol +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) + +} as const; +>const : Symbol(const) + +const anotherUnique = Symbol('symbols.anotherUnique'); +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 6, 5)) + +const Symbols2 = { +>Symbols2 : Symbol(Symbols2, Decl(uniqueSymbolReassignment.ts, 7, 5)) + + anotherUnique +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) + +} as const; +>const : Symbol(const) + +function myFunction() {} +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) + +// Attach the unique ones +myFunction.mySymbol = Symbols.mySymbol; +>myFunction.mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 11, 24)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 11, 24)) +>Symbols.mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) +>Symbols : Symbol(Symbols, Decl(uniqueSymbolReassignment.ts, 2, 5)) +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) + +myFunction.anotherUnique = Symbols2.anotherUnique; +>myFunction.anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 14, 39)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 14, 39)) +>Symbols2.anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) +>Symbols2 : Symbol(Symbols2, Decl(uniqueSymbolReassignment.ts, 7, 5)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) + +// Non-unique symbols (regular Symbol() without const) +const nonUniqueSymbol1 = Symbol('nonUnique1'); +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 5)) + +const nonUniqueSymbol2 = Symbol('nonUnique2'); +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 5)) + +// Plain text variables (not symbols at all) +const normalVar = "not a symbol"; +>normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 22, 5)) + +const symbolName = "this contains symbol but is not one"; +>symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 23, 5)) + +// Attach those as well +myFunction.nonUnique1 = nonUniqueSymbol1; +>myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 5)) + +myFunction.nonUnique2 = nonUniqueSymbol2; +>myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 5)) + +myFunction.normalVar = normalVar; +>myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 27, 41)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 27, 41)) +>normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 22, 5)) + +myFunction.symbolName = symbolName; +>myFunction.symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 28, 33)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 28, 33)) +>symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 23, 5)) + +export { myFunction }; +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 31, 8)) + diff --git a/tests/baselines/reference/uniqueSymbolReassignment.types b/tests/baselines/reference/uniqueSymbolReassignment.types new file mode 100644 index 0000000000000..13fc854ddbe78 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.types @@ -0,0 +1,176 @@ +//// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// + +=== uniqueSymbolReassignment.ts === +// This is a unique symbol (const + Symbol()) +const mySymbol = Symbol('Symbols.mySymbol'); +>mySymbol : any +> : ^^^ +>Symbol('Symbols.mySymbol') : any +> : ^^^ +>Symbol : any +> : ^^^ +>'Symbols.mySymbol' : "Symbols.mySymbol" +> : ^^^^^^^^^^^^^^^^^^ + +const Symbols = { +>Symbols : { readonly mySymbol: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ mySymbol} as const : { readonly mySymbol: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ mySymbol} : { readonly mySymbol: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + mySymbol +>mySymbol : any +> : ^^^ + +} as const; + +const anotherUnique = Symbol('symbols.anotherUnique'); +>anotherUnique : any +> : ^^^ +>Symbol('symbols.anotherUnique') : any +> : ^^^ +>Symbol : any +> : ^^^ +>'symbols.anotherUnique' : "symbols.anotherUnique" +> : ^^^^^^^^^^^^^^^^^^^^^^^ + +const Symbols2 = { +>Symbols2 : { readonly anotherUnique: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ anotherUnique} as const : { readonly anotherUnique: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ anotherUnique} : { readonly anotherUnique: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + anotherUnique +>anotherUnique : any +> : ^^^ + +} as const; + +function myFunction() {} +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ + +// Attach the unique ones +myFunction.mySymbol = Symbols.mySymbol; +>myFunction.mySymbol = Symbols.mySymbol : any +> : ^^^ +>myFunction.mySymbol : any +> : ^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>mySymbol : any +> : ^^^ +>Symbols.mySymbol : any +> : ^^^ +>Symbols : { readonly mySymbol: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mySymbol : any +> : ^^^ + +myFunction.anotherUnique = Symbols2.anotherUnique; +>myFunction.anotherUnique = Symbols2.anotherUnique : any +> : ^^^ +>myFunction.anotherUnique : any +> : ^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>anotherUnique : any +> : ^^^ +>Symbols2.anotherUnique : any +> : ^^^ +>Symbols2 : { readonly anotherUnique: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>anotherUnique : any +> : ^^^ + +// Non-unique symbols (regular Symbol() without const) +const nonUniqueSymbol1 = Symbol('nonUnique1'); +>nonUniqueSymbol1 : any +> : ^^^ +>Symbol('nonUnique1') : any +> : ^^^ +>Symbol : any +> : ^^^ +>'nonUnique1' : "nonUnique1" +> : ^^^^^^^^^^^^ + +const nonUniqueSymbol2 = Symbol('nonUnique2'); +>nonUniqueSymbol2 : any +> : ^^^ +>Symbol('nonUnique2') : any +> : ^^^ +>Symbol : any +> : ^^^ +>'nonUnique2' : "nonUnique2" +> : ^^^^^^^^^^^^ + +// Plain text variables (not symbols at all) +const normalVar = "not a symbol"; +>normalVar : "not a symbol" +> : ^^^^^^^^^^^^^^ +>"not a symbol" : "not a symbol" +> : ^^^^^^^^^^^^^^ + +const symbolName = "this contains symbol but is not one"; +>symbolName : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"this contains symbol but is not one" : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Attach those as well +myFunction.nonUnique1 = nonUniqueSymbol1; +>myFunction.nonUnique1 = nonUniqueSymbol1 : any +> : ^^^ +>myFunction.nonUnique1 : any +> : ^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>nonUnique1 : any +> : ^^^ +>nonUniqueSymbol1 : any +> : ^^^ + +myFunction.nonUnique2 = nonUniqueSymbol2; +>myFunction.nonUnique2 = nonUniqueSymbol2 : any +> : ^^^ +>myFunction.nonUnique2 : any +> : ^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>nonUnique2 : any +> : ^^^ +>nonUniqueSymbol2 : any +> : ^^^ + +myFunction.normalVar = normalVar; +>myFunction.normalVar = normalVar : "not a symbol" +> : ^^^^^^^^^^^^^^ +>myFunction.normalVar : string +> : ^^^^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>normalVar : string +> : ^^^^^^ +>normalVar : "not a symbol" +> : ^^^^^^^^^^^^^^ + +myFunction.symbolName = symbolName; +>myFunction.symbolName = symbolName : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>myFunction.symbolName : string +> : ^^^^^^ +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ +>symbolName : string +> : ^^^^^^ +>symbolName : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +export { myFunction }; +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ + diff --git a/tests/cases/compiler/uniqueSymbolReassignment.ts b/tests/cases/compiler/uniqueSymbolReassignment.ts new file mode 100644 index 0000000000000..ff704d59d7cf9 --- /dev/null +++ b/tests/cases/compiler/uniqueSymbolReassignment.ts @@ -0,0 +1,34 @@ +// @filename: uniqueSymbolReassignment.ts + +// This is a unique symbol (const + Symbol()) +const mySymbol = Symbol('Symbols.mySymbol'); +const Symbols = { + mySymbol +} as const; + +const anotherUnique = Symbol('symbols.anotherUnique'); +const Symbols2 = { + anotherUnique +} as const; + +function myFunction() {} + +// Attach the unique ones +myFunction.mySymbol = Symbols.mySymbol; +myFunction.anotherUnique = Symbols2.anotherUnique; + +// Non-unique symbols (regular Symbol() without const) +const nonUniqueSymbol1 = Symbol('nonUnique1'); +const nonUniqueSymbol2 = Symbol('nonUnique2'); + +// Plain text variables (not symbols at all) +const normalVar = "not a symbol"; +const symbolName = "this contains symbol but is not one"; + +// Attach those as well +myFunction.nonUnique1 = nonUniqueSymbol1; +myFunction.nonUnique2 = nonUniqueSymbol2; +myFunction.normalVar = normalVar; +myFunction.symbolName = symbolName; + +export { myFunction }; From 638c34f40a55e28606b43337ed0d0e9d8fd9fe7f Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 2 Sep 2025 14:47:00 +0530 Subject: [PATCH 02/11] chore: format code --- src/compiler/emitter.ts | 23 ++++++++++++----------- src/compiler/transformers/declarations.ts | 15 ++++++++------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c8834ee680c4e..1c2ce6741bc12 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -423,12 +423,14 @@ import { WriteFileCallbackData, YieldExpression, } from "./_namespaces/ts.js"; -import { isTypeReferenceNode, TypeFlags, TypeChecker } from "./_namespaces/ts.js"; +import { + isTypeReferenceNode, + TypeChecker, + TypeFlags, +} from "./_namespaces/ts.js"; import * as performance from "./_namespaces/ts.performance.js"; const brackets = createBracketsMap(); - - /** @internal */ export function isUniqueSymbolDeclaration(node: VariableDeclarationList, checker: TypeChecker): boolean { return node.declarations.some((decl: VariableDeclaration) => { @@ -457,7 +459,7 @@ export function isUniqueSymbolDeclaration(node: VariableDeclarationList, checker export function isBuildInfoFile(file: string): boolean { return fileExtensionIs(file, Extension.TsBuildInfo); } - + /** * Iterates over the source files that are expected to have an emit output. * @@ -3421,24 +3423,23 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeKeyword("await"); writeSpace(); writeKeyword("using"); - } else { + } + else { // Check if unique symbol and use const instead of var const isUnique = typeChecker && isUniqueSymbolDeclaration(node, typeChecker); - const head = - isLet(node) ? "let" : + const head = isLet(node) ? "let" : isVarConst(node) ? "const" : isVarUsing(node) ? "using" : isUnique ? "const" : "var"; - + writeKeyword(head); } - - writeSpace(); + + writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } - function emitFunctionDeclaration(node: FunctionDeclaration) { emitFunctionDeclarationOrExpression(node); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 370d7c889f73e..8bda645357b5f 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -141,12 +141,12 @@ import { isStringLiteralLike, isTupleTypeNode, isTypeAliasDeclaration, - isTypeReferenceNode, isTypeElement, isTypeLiteralNode, isTypeNode, isTypeParameterDeclaration, isTypeQueryNode, + isTypeReferenceNode, isVarAwaitUsing, isVariableDeclaration, isVarUsing, @@ -219,10 +219,9 @@ import { VisitResult, } from "../_namespaces/ts.js"; - function isUniqueSymbolByType(type: TypeNode | undefined): boolean { if (!type) return false; - + if (type.kind === SyntaxKind.TypeOperator && (type as any).operator === SyntaxKind.UniqueKeyword) return true; if (isTypeReferenceNode(type) && isIdentifier(type.typeName)) { @@ -1497,11 +1496,13 @@ export function transformDeclarations(context: TransformationContext): Transform const declList = factory.createVariableDeclarationList( [varDecl], - shouldForceConst ? NodeFlags.Const : NodeFlags.None + shouldForceConst ? NodeFlags.Const : NodeFlags.None, ); - + return factory.createVariableStatement( - isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)],declList); + isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], + declList, + ); }); if (!exportMappings.length) { declarations = mapDefined(declarations, declaration => factory.replaceModifiers(declaration, ModifierFlags.None)); @@ -1993,4 +1994,4 @@ function isProcessedComponent(node: Node): node is ProcessedComponent { return true; } return false; -} \ No newline at end of file +} From 270aaeee5319f554f4829d225e801fb040600057 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 2 Sep 2025 14:52:25 +0530 Subject: [PATCH 03/11] fix(compiler): remove unused export and unnecessary @internal from isUniqueSymbolDeclaration --- src/compiler/emitter.ts | 46 +++---------------- src/compiler/transformers/declarations.ts | 36 +++++---------- tests/baselines/reference/api/typescript.d.ts | 3 +- 3 files changed, 19 insertions(+), 66 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1c2ce6741bc12..c60fd92787275 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -423,39 +423,11 @@ import { WriteFileCallbackData, YieldExpression, } from "./_namespaces/ts.js"; -import { - isTypeReferenceNode, - TypeChecker, - TypeFlags, -} from "./_namespaces/ts.js"; import * as performance from "./_namespaces/ts.performance.js"; + const brackets = createBracketsMap(); /** @internal */ -export function isUniqueSymbolDeclaration(node: VariableDeclarationList, checker: TypeChecker): boolean { - return node.declarations.some((decl: VariableDeclaration) => { - // 1. If type is explicitly written, handle as before - const typeNode: TypeNode | undefined = decl.type; - if (typeNode) { - if (isTypeReferenceNode(typeNode) && isIdentifier(typeNode.typeName)) { - if (typeNode.typeName.escapedText.toString() === "unique symbol") { - return true; - } - } - if ((typeNode.kind as SyntaxKind) === SyntaxKind.UniqueKeyword) { - return true; - } - } - // 2. Otherwise, check the inferred type - const type = checker.getTypeAtLocation(decl.name); - if (type.flags & TypeFlags.UniqueESSymbol) { - return true; - } - - return false; - }); -} - export function isBuildInfoFile(file: string): boolean { return fileExtensionIs(file, Extension.TsBuildInfo); } @@ -769,7 +741,6 @@ export function emitFiles( onlyBuildInfo: boolean, forceDtsEmit?: boolean, skipBuildInfo?: boolean, - emitTypeChecker?: TypeChecker, ): EmitResult { // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 @@ -870,7 +841,7 @@ export function emitFiles( extendedDiagnostics: compilerOptions.extendedDiagnostics, }; - const typeChecker = emitTypeChecker; + // Create a printer to print the nodes const printer = createPrinter(printerOptions, { // resolver hooks hasGlobalName: resolver.hasGlobalName, @@ -879,11 +850,12 @@ export function emitFiles( onEmitNode: transform.emitNodeWithNotification, isEmitNotificationEnabled: transform.isEmitNotificationEnabled, substituteNode: transform.substituteNode, - }, typeChecker); + }); Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform"); printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform, printer, compilerOptions); + // Clean up emit nodes on parse tree transform.dispose(); if (emittedFilesList) { @@ -928,8 +900,6 @@ export function emitFiles( } } - // TypeChecker is already captured in the closure above - const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit; emitSkipped = emitSkipped || declBlocked; if (!declBlocked || forceDtsEmit) { @@ -1221,7 +1191,7 @@ export const createPrinterWithRemoveCommentsNeverAsciiEscape: () => Printer = /* /** @internal */ export const createPrinterWithRemoveCommentsOmitTrailingSemicolon: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true })); -export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}, typeChecker?: TypeChecker): Printer { +export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 /* eslint-disable no-var */ @@ -3373,6 +3343,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeSpace(); emit(node.caseBlock); } + function emitLabeledStatement(node: LabeledStatement) { emit(node.label); emitTokenWithComment(SyntaxKind.ColonToken, node.label.end, writePunctuation, node); @@ -3425,17 +3396,12 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeKeyword("using"); } else { - // Check if unique symbol and use const instead of var - const isUnique = typeChecker && isUniqueSymbolDeclaration(node, typeChecker); const head = isLet(node) ? "let" : isVarConst(node) ? "const" : isVarUsing(node) ? "using" : - isUnique ? "const" : "var"; - writeKeyword(head); } - writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 8bda645357b5f..9886d31897312 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -111,7 +111,6 @@ import { isFunctionDeclaration, isFunctionLike, isGlobalScopeAugmentation, - isIdentifier, isIdentifierText, isImportEqualsDeclaration, isIndexSignatureDeclaration, @@ -146,7 +145,6 @@ import { isTypeNode, isTypeParameterDeclaration, isTypeQueryNode, - isTypeReferenceNode, isVarAwaitUsing, isVariableDeclaration, isVarUsing, @@ -205,6 +203,7 @@ import { tryCast, TypeAliasDeclaration, TypeNode, + TypeOperatorNode, TypeParameterDeclaration, TypeReferenceNode, unescapeLeadingUnderscores, @@ -219,17 +218,6 @@ import { VisitResult, } from "../_namespaces/ts.js"; -function isUniqueSymbolByType(type: TypeNode | undefined): boolean { - if (!type) return false; - - if (type.kind === SyntaxKind.TypeOperator && (type as any).operator === SyntaxKind.UniqueKeyword) return true; - - if (isTypeReferenceNode(type) && isIdentifier(type.typeName)) { - if (type.typeName.escapedText === "unique symbol") return true; - } - return false; -} - /** @internal */ export function getDeclarationDiagnostics( host: EmitHost, @@ -1492,17 +1480,10 @@ export function transformDeclarations(context: TransformationContext): Transform exportMappings.push([name, nameStr]); } const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); - const shouldForceConst = isUniqueSymbolByType(type); - - const declList = factory.createVariableDeclarationList( - [varDecl], - shouldForceConst ? NodeFlags.Const : NodeFlags.None, - ); - - return factory.createVariableStatement( - isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], - declList, - ); + const modifiers = isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)]; + const isConst = isUniqueSymbolType(type); + const variableDeclarationList = factory.createVariableDeclarationList([varDecl], isConst ? NodeFlags.Const : NodeFlags.None); + return factory.createVariableStatement(modifiers, variableDeclarationList); }); if (!exportMappings.length) { declarations = mapDefined(declarations, declaration => factory.replaceModifiers(declaration, ModifierFlags.None)); @@ -1840,6 +1821,13 @@ export function transformDeclarations(context: TransformationContext): Transform return isExportAssignment(node) || isExportDeclaration(node); } + function isUniqueSymbolType(type: TypeNode | undefined): boolean { + return !!type && + type.kind === SyntaxKind.TypeOperator && + (type as TypeOperatorNode).operator === SyntaxKind.UniqueKeyword && + (type as TypeOperatorNode).type.kind === SyntaxKind.SymbolKeyword; + } + function hasScopeMarker(statements: readonly Statement[]) { return some(statements, isScopeMarker); } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 20dcd74f31b9b..943ff5e152290 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -9499,10 +9499,9 @@ declare namespace ts { * @param context A lexical environment context for the visitor. */ function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext | undefined, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; - function isBuildInfoFile(file: string): boolean; function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; - function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers, typeChecker?: TypeChecker): Printer; + function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer; enum ProgramUpdateLevel { /** Program is updated with same root file names and options */ Update = 0, From dca1f36f07643be6e8fba6c0ed833c43e695f797 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 9 Sep 2025 01:42:02 +0530 Subject: [PATCH 04/11] fix(compiler): enable declaration emit for uniqueSymbolReassignment test and accept baselines --- src/compiler/emitter.ts | 2 +- .../uniqueSymbolReassignment.d.symbols | 38 ++++++++++++++ .../uniqueSymbolReassignment.d.types | 51 +++++++++++++++++++ .../reference/uniqueSymbolReassignment.js | 13 +++++ .../compiler/uniqueSymbolReassignment.d.ts | 12 +++++ .../compiler/uniqueSymbolReassignment.ts | 2 +- 6 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.d.symbols create mode 100644 tests/baselines/reference/uniqueSymbolReassignment.d.types create mode 100644 tests/cases/compiler/uniqueSymbolReassignment.d.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c60fd92787275..78f3da5df636e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6362,4 +6362,4 @@ function getEmitListItem(emit: EmitFunction, parenthesizerRule: return emit.length === 1 ? emitListItemNoParenthesizer as EmitListItemFunction : typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector as EmitListItemFunction : emitListItemWithParenthesizerRule as EmitListItemFunction; -} +} \ No newline at end of file diff --git a/tests/baselines/reference/uniqueSymbolReassignment.d.symbols b/tests/baselines/reference/uniqueSymbolReassignment.d.symbols new file mode 100644 index 0000000000000..e3465d934518d --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.d.symbols @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/uniqueSymbolReassignment.d.ts] //// + +=== uniqueSymbolReassignment.d.ts === +declare function myFunction(): void; +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 0, 0), Decl(uniqueSymbolReassignment.d.ts, 0, 36)) + +declare namespace myFunction { +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 0, 0), Decl(uniqueSymbolReassignment.d.ts, 0, 36)) + + const mySymbol: unique symbol; +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.d.ts, 2, 9)) + + const anotherUnique: unique symbol; +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.d.ts, 3, 9)) + + var nonUnique1: typeof nonUniqueSymbol1; +>nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolReassignment.d.ts, 4, 7)) +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.d.ts, 9, 13)) + + var nonUnique2: typeof nonUniqueSymbol2; +>nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolReassignment.d.ts, 5, 7)) +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.d.ts, 10, 13)) + + var normalVar: string; +>normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.d.ts, 6, 7)) + + var symbolName: string; +>symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.d.ts, 7, 7)) +} +declare const nonUniqueSymbol1: unique symbol; +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.d.ts, 9, 13)) + +declare const nonUniqueSymbol2: unique symbol; +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.d.ts, 10, 13)) + +export { myFunction }; +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 11, 8)) + diff --git a/tests/baselines/reference/uniqueSymbolReassignment.d.types b/tests/baselines/reference/uniqueSymbolReassignment.d.types new file mode 100644 index 0000000000000..c7ddec0537afc --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolReassignment.d.types @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/uniqueSymbolReassignment.d.ts] //// + +=== uniqueSymbolReassignment.d.ts === +declare function myFunction(): void; +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ + +declare namespace myFunction { +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ + + const mySymbol: unique symbol; +>mySymbol : unique symbol +> : ^^^^^^^^^^^^^ + + const anotherUnique: unique symbol; +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ + + var nonUnique1: typeof nonUniqueSymbol1; +>nonUnique1 : unique symbol +> : ^^^^^^^^^^^^^ +>nonUniqueSymbol1 : unique symbol +> : ^^^^^^^^^^^^^ + + var nonUnique2: typeof nonUniqueSymbol2; +>nonUnique2 : unique symbol +> : ^^^^^^^^^^^^^ +>nonUniqueSymbol2 : unique symbol +> : ^^^^^^^^^^^^^ + + var normalVar: string; +>normalVar : string +> : ^^^^^^ + + var symbolName: string; +>symbolName : string +> : ^^^^^^ +} +declare const nonUniqueSymbol1: unique symbol; +>nonUniqueSymbol1 : unique symbol +> : ^^^^^^^^^^^^^ + +declare const nonUniqueSymbol2: unique symbol; +>nonUniqueSymbol2 : unique symbol +> : ^^^^^^^^^^^^^ + +export { myFunction }; +>myFunction : typeof myFunction +> : ^^^^^^^^^^^^^^^^^ + diff --git a/tests/baselines/reference/uniqueSymbolReassignment.js b/tests/baselines/reference/uniqueSymbolReassignment.js index 61318f7f9e92d..20e450ba57a9c 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.js +++ b/tests/baselines/reference/uniqueSymbolReassignment.js @@ -63,3 +63,16 @@ myFunction.nonUnique1 = nonUniqueSymbol1; myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; + + +//// [uniqueSymbolReassignment.d.ts] +declare function myFunction(): void; +declare namespace myFunction { + var mySymbol: any; + var anotherUnique: any; + var nonUnique1: any; + var nonUnique2: any; + var normalVar: string; + var symbolName: string; +} +export { myFunction }; diff --git a/tests/cases/compiler/uniqueSymbolReassignment.d.ts b/tests/cases/compiler/uniqueSymbolReassignment.d.ts new file mode 100644 index 0000000000000..0b054a291e05e --- /dev/null +++ b/tests/cases/compiler/uniqueSymbolReassignment.d.ts @@ -0,0 +1,12 @@ +declare function myFunction(): void; +declare namespace myFunction { + const mySymbol: unique symbol; + const anotherUnique: unique symbol; + var nonUnique1: typeof nonUniqueSymbol1; + var nonUnique2: typeof nonUniqueSymbol2; + var normalVar: string; + var symbolName: string; +} +declare const nonUniqueSymbol1: unique symbol; +declare const nonUniqueSymbol2: unique symbol; +export { myFunction }; diff --git a/tests/cases/compiler/uniqueSymbolReassignment.ts b/tests/cases/compiler/uniqueSymbolReassignment.ts index ff704d59d7cf9..7e39033603ef0 100644 --- a/tests/cases/compiler/uniqueSymbolReassignment.ts +++ b/tests/cases/compiler/uniqueSymbolReassignment.ts @@ -1,5 +1,5 @@ // @filename: uniqueSymbolReassignment.ts - +// @declaration: true // This is a unique symbol (const + Symbol()) const mySymbol = Symbol('Symbols.mySymbol'); const Symbols = { From 5db056059945392b803ee8ff015381ae0de520e5 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 9 Sep 2025 01:52:18 +0530 Subject: [PATCH 05/11] Fix formatting for emitter.ts (LF line endings) --- src/compiler/emitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 78f3da5df636e..c60fd92787275 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6362,4 +6362,4 @@ function getEmitListItem(emit: EmitFunction, parenthesizerRule: return emit.length === 1 ? emitListItemNoParenthesizer as EmitListItemFunction : typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector as EmitListItemFunction : emitListItemWithParenthesizerRule as EmitListItemFunction; -} \ No newline at end of file +} From 89fd4f0ea1bff32cf014a15c83f514b1fd3c18e4 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Wed, 10 Sep 2025 01:48:44 +0530 Subject: [PATCH 06/11] test(compiler): remove stray baselines and add correct uniqueSymbolReassignment outputs --- .../uniqueSymbolReassignment.d.symbols | 38 ---- .../uniqueSymbolReassignment.d.types | 51 ------ .../uniqueSymbolReassignment.errors.txt | 48 ----- .../reference/uniqueSymbolReassignment.js | 15 +- .../uniqueSymbolReassignment.symbols | 16 +- .../reference/uniqueSymbolReassignment.types | 164 +++++++++--------- .../compiler/uniqueSymbolReassignment.ts | 7 +- 7 files changed, 103 insertions(+), 236 deletions(-) delete mode 100644 tests/baselines/reference/uniqueSymbolReassignment.d.symbols delete mode 100644 tests/baselines/reference/uniqueSymbolReassignment.d.types delete mode 100644 tests/baselines/reference/uniqueSymbolReassignment.errors.txt diff --git a/tests/baselines/reference/uniqueSymbolReassignment.d.symbols b/tests/baselines/reference/uniqueSymbolReassignment.d.symbols deleted file mode 100644 index e3465d934518d..0000000000000 --- a/tests/baselines/reference/uniqueSymbolReassignment.d.symbols +++ /dev/null @@ -1,38 +0,0 @@ -//// [tests/cases/compiler/uniqueSymbolReassignment.d.ts] //// - -=== uniqueSymbolReassignment.d.ts === -declare function myFunction(): void; ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 0, 0), Decl(uniqueSymbolReassignment.d.ts, 0, 36)) - -declare namespace myFunction { ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 0, 0), Decl(uniqueSymbolReassignment.d.ts, 0, 36)) - - const mySymbol: unique symbol; ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.d.ts, 2, 9)) - - const anotherUnique: unique symbol; ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.d.ts, 3, 9)) - - var nonUnique1: typeof nonUniqueSymbol1; ->nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolReassignment.d.ts, 4, 7)) ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.d.ts, 9, 13)) - - var nonUnique2: typeof nonUniqueSymbol2; ->nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolReassignment.d.ts, 5, 7)) ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.d.ts, 10, 13)) - - var normalVar: string; ->normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.d.ts, 6, 7)) - - var symbolName: string; ->symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.d.ts, 7, 7)) -} -declare const nonUniqueSymbol1: unique symbol; ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.d.ts, 9, 13)) - -declare const nonUniqueSymbol2: unique symbol; ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.d.ts, 10, 13)) - -export { myFunction }; ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.d.ts, 11, 8)) - diff --git a/tests/baselines/reference/uniqueSymbolReassignment.d.types b/tests/baselines/reference/uniqueSymbolReassignment.d.types deleted file mode 100644 index c7ddec0537afc..0000000000000 --- a/tests/baselines/reference/uniqueSymbolReassignment.d.types +++ /dev/null @@ -1,51 +0,0 @@ -//// [tests/cases/compiler/uniqueSymbolReassignment.d.ts] //// - -=== uniqueSymbolReassignment.d.ts === -declare function myFunction(): void; ->myFunction : typeof myFunction -> : ^^^^^^^^^^^^^^^^^ - -declare namespace myFunction { ->myFunction : typeof myFunction -> : ^^^^^^^^^^^^^^^^^ - - const mySymbol: unique symbol; ->mySymbol : unique symbol -> : ^^^^^^^^^^^^^ - - const anotherUnique: unique symbol; ->anotherUnique : unique symbol -> : ^^^^^^^^^^^^^ - - var nonUnique1: typeof nonUniqueSymbol1; ->nonUnique1 : unique symbol -> : ^^^^^^^^^^^^^ ->nonUniqueSymbol1 : unique symbol -> : ^^^^^^^^^^^^^ - - var nonUnique2: typeof nonUniqueSymbol2; ->nonUnique2 : unique symbol -> : ^^^^^^^^^^^^^ ->nonUniqueSymbol2 : unique symbol -> : ^^^^^^^^^^^^^ - - var normalVar: string; ->normalVar : string -> : ^^^^^^ - - var symbolName: string; ->symbolName : string -> : ^^^^^^ -} -declare const nonUniqueSymbol1: unique symbol; ->nonUniqueSymbol1 : unique symbol -> : ^^^^^^^^^^^^^ - -declare const nonUniqueSymbol2: unique symbol; ->nonUniqueSymbol2 : unique symbol -> : ^^^^^^^^^^^^^ - -export { myFunction }; ->myFunction : typeof myFunction -> : ^^^^^^^^^^^^^^^^^ - diff --git a/tests/baselines/reference/uniqueSymbolReassignment.errors.txt b/tests/baselines/reference/uniqueSymbolReassignment.errors.txt deleted file mode 100644 index 9914be5cac584..0000000000000 --- a/tests/baselines/reference/uniqueSymbolReassignment.errors.txt +++ /dev/null @@ -1,48 +0,0 @@ -uniqueSymbolReassignment.ts(2,18): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. -uniqueSymbolReassignment.ts(7,23): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. -uniqueSymbolReassignment.ts(19,26): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. -uniqueSymbolReassignment.ts(20,26): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - - -==== uniqueSymbolReassignment.ts (4 errors) ==== - // This is a unique symbol (const + Symbol()) - const mySymbol = Symbol('Symbols.mySymbol'); - ~~~~~~ -!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - const Symbols = { - mySymbol - } as const; - - const anotherUnique = Symbol('symbols.anotherUnique'); - ~~~~~~ -!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - const Symbols2 = { - anotherUnique - } as const; - - function myFunction() {} - - // Attach the unique ones - myFunction.mySymbol = Symbols.mySymbol; - myFunction.anotherUnique = Symbols2.anotherUnique; - - // Non-unique symbols (regular Symbol() without const) - const nonUniqueSymbol1 = Symbol('nonUnique1'); - ~~~~~~ -!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - const nonUniqueSymbol2 = Symbol('nonUnique2'); - ~~~~~~ -!!! error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - - // Plain text variables (not symbols at all) - const normalVar = "not a symbol"; - const symbolName = "this contains symbol but is not one"; - - // Attach those as well - myFunction.nonUnique1 = nonUniqueSymbol1; - myFunction.nonUnique2 = nonUniqueSymbol2; - myFunction.normalVar = normalVar; - myFunction.symbolName = symbolName; - - export { myFunction }; - \ No newline at end of file diff --git a/tests/baselines/reference/uniqueSymbolReassignment.js b/tests/baselines/reference/uniqueSymbolReassignment.js index 20e450ba57a9c..484b12c0f67b1 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.js +++ b/tests/baselines/reference/uniqueSymbolReassignment.js @@ -19,8 +19,8 @@ myFunction.mySymbol = Symbols.mySymbol; myFunction.anotherUnique = Symbols2.anotherUnique; // Non-unique symbols (regular Symbol() without const) -const nonUniqueSymbol1 = Symbol('nonUnique1'); -const nonUniqueSymbol2 = Symbol('nonUnique2'); +let nonUniqueSymbol1 = Symbol('nonUnique1'); +let nonUniqueSymbol2 = Symbol('nonUnique2'); // Plain text variables (not symbols at all) const normalVar = "not a symbol"; @@ -32,8 +32,7 @@ myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -export { myFunction }; - +export { myFunction }; //// [uniqueSymbolReassignment.js] "use strict"; @@ -68,10 +67,10 @@ myFunction.symbolName = symbolName; //// [uniqueSymbolReassignment.d.ts] declare function myFunction(): void; declare namespace myFunction { - var mySymbol: any; - var anotherUnique: any; - var nonUnique1: any; - var nonUnique2: any; + const mySymbol: unique symbol; + const anotherUnique: unique symbol; + var nonUnique1: symbol; + var nonUnique2: symbol; var normalVar: string; var symbolName: string; } diff --git a/tests/baselines/reference/uniqueSymbolReassignment.symbols b/tests/baselines/reference/uniqueSymbolReassignment.symbols index 740ae2dfb3b0f..99f8a810b7d4b 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.symbols +++ b/tests/baselines/reference/uniqueSymbolReassignment.symbols @@ -4,6 +4,7 @@ // This is a unique symbol (const + Symbol()) const mySymbol = Symbol('Symbols.mySymbol'); >mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 1, 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 Symbols = { >Symbols : Symbol(Symbols, Decl(uniqueSymbolReassignment.ts, 2, 5)) @@ -16,6 +17,7 @@ const Symbols = { const anotherUnique = Symbol('symbols.anotherUnique'); >anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 6, 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 Symbols2 = { >Symbols2 : Symbol(Symbols2, Decl(uniqueSymbolReassignment.ts, 7, 5)) @@ -47,11 +49,13 @@ myFunction.anotherUnique = Symbols2.anotherUnique; >anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) // Non-unique symbols (regular Symbol() without const) -const nonUniqueSymbol1 = Symbol('nonUnique1'); ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 5)) +let nonUniqueSymbol1 = Symbol('nonUnique1'); +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 3)) +>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 nonUniqueSymbol2 = Symbol('nonUnique2'); ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 5)) +let nonUniqueSymbol2 = Symbol('nonUnique2'); +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 3)) +>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, --, --)) // Plain text variables (not symbols at all) const normalVar = "not a symbol"; @@ -65,13 +69,13 @@ myFunction.nonUnique1 = nonUniqueSymbol1; >myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) >myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) >nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 5)) +>nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 3)) myFunction.nonUnique2 = nonUniqueSymbol2; >myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) >myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) >nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 5)) +>nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 3)) myFunction.normalVar = normalVar; >myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 27, 41)) diff --git a/tests/baselines/reference/uniqueSymbolReassignment.types b/tests/baselines/reference/uniqueSymbolReassignment.types index 13fc854ddbe78..07068bfb3c574 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.types +++ b/tests/baselines/reference/uniqueSymbolReassignment.types @@ -3,50 +3,50 @@ === uniqueSymbolReassignment.ts === // This is a unique symbol (const + Symbol()) const mySymbol = Symbol('Symbols.mySymbol'); ->mySymbol : any -> : ^^^ ->Symbol('Symbols.mySymbol') : any -> : ^^^ ->Symbol : any -> : ^^^ +>mySymbol : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol('Symbols.mySymbol') : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ >'Symbols.mySymbol' : "Symbols.mySymbol" > : ^^^^^^^^^^^^^^^^^^ const Symbols = { ->Symbols : { readonly mySymbol: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ mySymbol} as const : { readonly mySymbol: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ mySymbol} : { readonly mySymbol: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Symbols : { readonly mySymbol: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ mySymbol} as const : { readonly mySymbol: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ mySymbol} : { readonly mySymbol: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mySymbol ->mySymbol : any -> : ^^^ +>mySymbol : unique symbol +> : ^^^^^^^^^^^^^ } as const; const anotherUnique = Symbol('symbols.anotherUnique'); ->anotherUnique : any -> : ^^^ ->Symbol('symbols.anotherUnique') : any -> : ^^^ ->Symbol : any -> : ^^^ +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol('symbols.anotherUnique') : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ >'symbols.anotherUnique' : "symbols.anotherUnique" > : ^^^^^^^^^^^^^^^^^^^^^^^ const Symbols2 = { ->Symbols2 : { readonly anotherUnique: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ anotherUnique} as const : { readonly anotherUnique: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ anotherUnique} : { readonly anotherUnique: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Symbols2 : { readonly anotherUnique: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ anotherUnique} as const : { readonly anotherUnique: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ anotherUnique} : { readonly anotherUnique: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ anotherUnique ->anotherUnique : any -> : ^^^ +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ } as const; @@ -56,55 +56,55 @@ function myFunction() {} // Attach the unique ones myFunction.mySymbol = Symbols.mySymbol; ->myFunction.mySymbol = Symbols.mySymbol : any -> : ^^^ ->myFunction.mySymbol : any -> : ^^^ +>myFunction.mySymbol = Symbols.mySymbol : unique symbol +> : ^^^^^^^^^^^^^ +>myFunction.mySymbol : unique symbol +> : ^^^^^^^^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ ->mySymbol : any -> : ^^^ ->Symbols.mySymbol : any -> : ^^^ ->Symbols : { readonly mySymbol: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->mySymbol : any -> : ^^^ +>mySymbol : unique symbol +> : ^^^^^^^^^^^^^ +>Symbols.mySymbol : unique symbol +> : ^^^^^^^^^^^^^ +>Symbols : { readonly mySymbol: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mySymbol : unique symbol +> : ^^^^^^^^^^^^^ myFunction.anotherUnique = Symbols2.anotherUnique; ->myFunction.anotherUnique = Symbols2.anotherUnique : any -> : ^^^ ->myFunction.anotherUnique : any -> : ^^^ +>myFunction.anotherUnique = Symbols2.anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ +>myFunction.anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ ->anotherUnique : any -> : ^^^ ->Symbols2.anotherUnique : any -> : ^^^ ->Symbols2 : { readonly anotherUnique: any; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->anotherUnique : any -> : ^^^ +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ +>Symbols2.anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ +>Symbols2 : { readonly anotherUnique: unique symbol; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ // Non-unique symbols (regular Symbol() without const) -const nonUniqueSymbol1 = Symbol('nonUnique1'); ->nonUniqueSymbol1 : any -> : ^^^ ->Symbol('nonUnique1') : any -> : ^^^ ->Symbol : any -> : ^^^ +let nonUniqueSymbol1 = Symbol('nonUnique1'); +>nonUniqueSymbol1 : symbol +> : ^^^^^^ +>Symbol('nonUnique1') : symbol +> : ^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ >'nonUnique1' : "nonUnique1" > : ^^^^^^^^^^^^ -const nonUniqueSymbol2 = Symbol('nonUnique2'); ->nonUniqueSymbol2 : any -> : ^^^ ->Symbol('nonUnique2') : any -> : ^^^ ->Symbol : any -> : ^^^ +let nonUniqueSymbol2 = Symbol('nonUnique2'); +>nonUniqueSymbol2 : symbol +> : ^^^^^^ +>Symbol('nonUnique2') : symbol +> : ^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ >'nonUnique2' : "nonUnique2" > : ^^^^^^^^^^^^ @@ -123,28 +123,28 @@ const symbolName = "this contains symbol but is not one"; // Attach those as well myFunction.nonUnique1 = nonUniqueSymbol1; ->myFunction.nonUnique1 = nonUniqueSymbol1 : any -> : ^^^ ->myFunction.nonUnique1 : any -> : ^^^ +>myFunction.nonUnique1 = nonUniqueSymbol1 : symbol +> : ^^^^^^ +>myFunction.nonUnique1 : symbol +> : ^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ ->nonUnique1 : any -> : ^^^ ->nonUniqueSymbol1 : any -> : ^^^ +>nonUnique1 : symbol +> : ^^^^^^ +>nonUniqueSymbol1 : symbol +> : ^^^^^^ myFunction.nonUnique2 = nonUniqueSymbol2; ->myFunction.nonUnique2 = nonUniqueSymbol2 : any -> : ^^^ ->myFunction.nonUnique2 : any -> : ^^^ +>myFunction.nonUnique2 = nonUniqueSymbol2 : symbol +> : ^^^^^^ +>myFunction.nonUnique2 : symbol +> : ^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ ->nonUnique2 : any -> : ^^^ ->nonUniqueSymbol2 : any -> : ^^^ +>nonUnique2 : symbol +> : ^^^^^^ +>nonUniqueSymbol2 : symbol +> : ^^^^^^ myFunction.normalVar = normalVar; >myFunction.normalVar = normalVar : "not a symbol" diff --git a/tests/cases/compiler/uniqueSymbolReassignment.ts b/tests/cases/compiler/uniqueSymbolReassignment.ts index 7e39033603ef0..041387c4b2cd7 100644 --- a/tests/cases/compiler/uniqueSymbolReassignment.ts +++ b/tests/cases/compiler/uniqueSymbolReassignment.ts @@ -1,5 +1,6 @@ // @filename: uniqueSymbolReassignment.ts // @declaration: true +// @lib: esnext // This is a unique symbol (const + Symbol()) const mySymbol = Symbol('Symbols.mySymbol'); const Symbols = { @@ -18,8 +19,8 @@ myFunction.mySymbol = Symbols.mySymbol; myFunction.anotherUnique = Symbols2.anotherUnique; // Non-unique symbols (regular Symbol() without const) -const nonUniqueSymbol1 = Symbol('nonUnique1'); -const nonUniqueSymbol2 = Symbol('nonUnique2'); +let nonUniqueSymbol1 = Symbol('nonUnique1'); +let nonUniqueSymbol2 = Symbol('nonUnique2'); // Plain text variables (not symbols at all) const normalVar = "not a symbol"; @@ -31,4 +32,4 @@ myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -export { myFunction }; +export { myFunction }; \ No newline at end of file From 9e6554fe259bb478c26de49c927672b52fc37105 Mon Sep 17 00:00:00 2001 From: Akshit Bhatt Date: Wed, 10 Sep 2025 01:55:12 +0530 Subject: [PATCH 07/11] Delete tests/cases/compiler/uniqueSymbolReassignment.d.ts --- tests/cases/compiler/uniqueSymbolReassignment.d.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 tests/cases/compiler/uniqueSymbolReassignment.d.ts diff --git a/tests/cases/compiler/uniqueSymbolReassignment.d.ts b/tests/cases/compiler/uniqueSymbolReassignment.d.ts deleted file mode 100644 index 0b054a291e05e..0000000000000 --- a/tests/cases/compiler/uniqueSymbolReassignment.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare function myFunction(): void; -declare namespace myFunction { - const mySymbol: unique symbol; - const anotherUnique: unique symbol; - var nonUnique1: typeof nonUniqueSymbol1; - var nonUnique2: typeof nonUniqueSymbol2; - var normalVar: string; - var symbolName: string; -} -declare const nonUniqueSymbol1: unique symbol; -declare const nonUniqueSymbol2: unique symbol; -export { myFunction }; From b43965c83bedd33d969a7f22a42b91b6de8ab517 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Mon, 29 Sep 2025 23:29:14 +0530 Subject: [PATCH 08/11] fix(declarations): emit ypeof for exported unique symbols --- src/compiler/transformers/declarations.ts | 21 ++- .../reference/uniqueSymbolReassignment.js | 110 ++++++++------ .../uniqueSymbolReassignment.symbols | 129 ++++++++--------- .../reference/uniqueSymbolReassignment.types | 134 +++++++----------- .../compiler/uniqueSymbolReassignment.ts | 43 +++--- 5 files changed, 222 insertions(+), 215 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 9886d31897312..e01e0f16eda8e 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -217,7 +217,8 @@ import { visitNodes, VisitResult, } from "../_namespaces/ts.js"; - +import { collectExternalModuleInfo } from "./utilities.js"; +import { PrivateIdentifier, isIdentifier, idText } from "../_namespaces/ts.js"; /** @internal */ export function getDeclarationDiagnostics( host: EmitHost, @@ -1463,6 +1464,15 @@ export function transformDeclarations(context: TransformationContext): Transform fakespace.locals = createSymbolTable(props); fakespace.symbol = props[0].parent!; const exportMappings: [Identifier, string][] = []; + + // Before emitting expando properties, get all exported names for the file + const moduleInfo = collectExternalModuleInfo(context, input.parent as SourceFile); + const topLevelExportNames = new Set( + (moduleInfo.exportedNames ?? []) + .filter(n => isIdentifier(n) || isPrivateIdentifier(n)) + .map(n => idText(n as Identifier | PrivateIdentifier)) + ); + let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => { if (!isExpandoPropertyDeclaration(p.valueDeclaration)) { return undefined; @@ -1472,7 +1482,12 @@ export function transformDeclarations(context: TransformationContext): Transform return undefined; // unique symbol or non-identifier name - omit, since there's no syntax that can preserve it } getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration); - const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags | InternalNodeBuilderFlags.NoSyntacticPrinter, symbolTracker); + let type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags | InternalNodeBuilderFlags.NoSyntacticPrinter, symbolTracker); + const wasUniqueSymbol = isUniqueSymbolType(type); + // If this is a unique symbol and also exported at the top level, emit typeof + if (wasUniqueSymbol && topLevelExportNames.has(nameStr)) { + type = factory.createTypeQueryNode(factory.createIdentifier(nameStr)); + } getSymbolAccessibilityDiagnostic = oldDiag; const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr); const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr); @@ -1481,7 +1496,7 @@ export function transformDeclarations(context: TransformationContext): Transform } const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); const modifiers = isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)]; - const isConst = isUniqueSymbolType(type); + const isConst = wasUniqueSymbol; const variableDeclarationList = factory.createVariableDeclarationList([varDecl], isConst ? NodeFlags.Const : NodeFlags.None); return factory.createVariableStatement(modifiers, variableDeclarationList); }); diff --git a/tests/baselines/reference/uniqueSymbolReassignment.js b/tests/baselines/reference/uniqueSymbolReassignment.js index 484b12c0f67b1..8f77cbaac9566 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.js +++ b/tests/baselines/reference/uniqueSymbolReassignment.js @@ -1,77 +1,105 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -//// [uniqueSymbolReassignment.ts] -// This is a unique symbol (const + Symbol()) +//// [uniqueSymbolFullTest.ts] +// ------------------------- +// Explicit unique symbols (should emit `const` / `typeof` when exported) +// ------------------------- const mySymbol = Symbol('Symbols.mySymbol'); -const Symbols = { - mySymbol -} as const; - const anotherUnique = Symbol('symbols.anotherUnique'); -const Symbols2 = { - anotherUnique -} as const; function myFunction() {} // Attach the unique ones -myFunction.mySymbol = Symbols.mySymbol; -myFunction.anotherUnique = Symbols2.anotherUnique; +myFunction.mySymbol = mySymbol; +myFunction.anotherUnique = anotherUnique; + +// ------------------------- +// Non-unique symbols (should stay `var`) +// ------------------------- +let nonUnique1 = Symbol('nonUnique1'); +let nonUnique2 = Symbol('nonUnique2'); -// Non-unique symbols (regular Symbol() without const) -let nonUniqueSymbol1 = Symbol('nonUnique1'); -let nonUniqueSymbol2 = Symbol('nonUnique2'); +myFunction.nonUnique1 = nonUnique1; +myFunction.nonUnique2 = nonUnique2; -// Plain text variables (not symbols at all) -const normalVar = "not a symbol"; +// ------------------------- +// Normal variables (should stay `var`/string) +// ------------------------- +const normalVar = "just a string"; const symbolName = "this contains symbol but is not one"; -// Attach those as well -myFunction.nonUnique1 = nonUniqueSymbol1; -myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -export { myFunction }; +// ------------------------- +// Export symbols along with function to test `typeof` behavior +// ------------------------- +export { myFunction, anotherUnique }; + -//// [uniqueSymbolReassignment.js] +//// [uniqueSymbolFullTest.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.anotherUnique = void 0; exports.myFunction = myFunction; -// This is a unique symbol (const + Symbol()) +// ------------------------- +// Explicit unique symbols (should emit `const` / `typeof` when exported) +// ------------------------- var mySymbol = Symbol('Symbols.mySymbol'); -var Symbols = { - mySymbol: mySymbol -}; var anotherUnique = Symbol('symbols.anotherUnique'); -var Symbols2 = { - anotherUnique: anotherUnique -}; +exports.anotherUnique = anotherUnique; function myFunction() { } // Attach the unique ones -myFunction.mySymbol = Symbols.mySymbol; -myFunction.anotherUnique = Symbols2.anotherUnique; -// Non-unique symbols (regular Symbol() without const) -var nonUniqueSymbol1 = Symbol('nonUnique1'); -var nonUniqueSymbol2 = Symbol('nonUnique2'); -// Plain text variables (not symbols at all) -var normalVar = "not a symbol"; +myFunction.mySymbol = mySymbol; +myFunction.anotherUnique = anotherUnique; +// ------------------------- +// Non-unique symbols (should stay `var`) +// ------------------------- +var nonUnique1 = Symbol('nonUnique1'); +var nonUnique2 = Symbol('nonUnique2'); +myFunction.nonUnique1 = nonUnique1; +myFunction.nonUnique2 = nonUnique2; +// ------------------------- +// Normal variables (should stay `var`/string) +// ------------------------- +var normalVar = "just a string"; var symbolName = "this contains symbol but is not one"; -// Attach those as well -myFunction.nonUnique1 = nonUniqueSymbol1; -myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -//// [uniqueSymbolReassignment.d.ts] +//// [uniqueSymbolFullTest.d.ts] +declare const anotherUnique: unique symbol; declare function myFunction(): void; declare namespace myFunction { const mySymbol: unique symbol; - const anotherUnique: unique symbol; + const anotherUnique: typeof anotherUnique; var nonUnique1: symbol; var nonUnique2: symbol; var normalVar: string; var symbolName: string; } -export { myFunction }; +export { myFunction, anotherUnique }; + + +//// [DtsFileErrors] + + +uniqueSymbolFullTest.d.ts(5,11): error TS2502: 'anotherUnique' is referenced directly or indirectly in its own type annotation. + + +==== uniqueSymbolFullTest.d.ts (1 errors) ==== + declare const anotherUnique: unique symbol; + declare function myFunction(): void; + declare namespace myFunction { + const mySymbol: unique symbol; + const anotherUnique: typeof anotherUnique; + ~~~~~~~~~~~~~ +!!! error TS2502: 'anotherUnique' is referenced directly or indirectly in its own type annotation. + var nonUnique1: symbol; + var nonUnique2: symbol; + var normalVar: string; + var symbolName: string; + } + export { myFunction, anotherUnique }; + \ No newline at end of file diff --git a/tests/baselines/reference/uniqueSymbolReassignment.symbols b/tests/baselines/reference/uniqueSymbolReassignment.symbols index 99f8a810b7d4b..a721d2d339f13 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.symbols +++ b/tests/baselines/reference/uniqueSymbolReassignment.symbols @@ -1,94 +1,81 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -=== uniqueSymbolReassignment.ts === -// This is a unique symbol (const + Symbol()) +=== uniqueSymbolFullTest.ts === +// ------------------------- +// Explicit unique symbols (should emit `const` / `typeof` when exported) +// ------------------------- const mySymbol = Symbol('Symbols.mySymbol'); ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 1, 5)) +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolFullTest.ts, 3, 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 Symbols = { ->Symbols : Symbol(Symbols, Decl(uniqueSymbolReassignment.ts, 2, 5)) - - mySymbol ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) - -} as const; ->const : Symbol(const) - const anotherUnique = Symbol('symbols.anotherUnique'); ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 6, 5)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 4, 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 Symbols2 = { ->Symbols2 : Symbol(Symbols2, Decl(uniqueSymbolReassignment.ts, 7, 5)) - - anotherUnique ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) - -} as const; ->const : Symbol(const) - function myFunction() {} ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) // Attach the unique ones -myFunction.mySymbol = Symbols.mySymbol; ->myFunction.mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 11, 24)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 11, 24)) ->Symbols.mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) ->Symbols : Symbol(Symbols, Decl(uniqueSymbolReassignment.ts, 2, 5)) ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 2, 17)) - -myFunction.anotherUnique = Symbols2.anotherUnique; ->myFunction.anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 14, 39)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 14, 39)) ->Symbols2.anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) ->Symbols2 : Symbol(Symbols2, Decl(uniqueSymbolReassignment.ts, 7, 5)) ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 7, 18)) - -// Non-unique symbols (regular Symbol() without const) -let nonUniqueSymbol1 = Symbol('nonUnique1'); ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 3)) +myFunction.mySymbol = mySymbol; +>myFunction.mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolFullTest.ts, 6, 24)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolFullTest.ts, 6, 24)) +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolFullTest.ts, 3, 5)) + +myFunction.anotherUnique = anotherUnique; +>myFunction.anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolFullTest.ts, 9, 31)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolFullTest.ts, 9, 31)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 4, 5)) + +// ------------------------- +// Non-unique symbols (should stay `var`) +// ------------------------- +let nonUnique1 = Symbol('nonUnique1'); +>nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolFullTest.ts, 15, 3)) >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, --, --)) -let nonUniqueSymbol2 = Symbol('nonUnique2'); ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 3)) +let nonUnique2 = Symbol('nonUnique2'); +>nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolFullTest.ts, 16, 3)) >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, --, --)) -// Plain text variables (not symbols at all) -const normalVar = "not a symbol"; ->normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 22, 5)) +myFunction.nonUnique1 = nonUnique1; +>myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolFullTest.ts, 16, 38)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolFullTest.ts, 16, 38)) +>nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolFullTest.ts, 15, 3)) -const symbolName = "this contains symbol but is not one"; ->symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 23, 5)) +myFunction.nonUnique2 = nonUnique2; +>myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolFullTest.ts, 18, 35)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolFullTest.ts, 18, 35)) +>nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolFullTest.ts, 16, 3)) -// Attach those as well -myFunction.nonUnique1 = nonUniqueSymbol1; ->myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 23, 57)) ->nonUniqueSymbol1 : Symbol(nonUniqueSymbol1, Decl(uniqueSymbolReassignment.ts, 18, 3)) +// ------------------------- +// Normal variables (should stay `var`/string) +// ------------------------- +const normalVar = "just a string"; +>normalVar : Symbol(normalVar, Decl(uniqueSymbolFullTest.ts, 24, 5)) -myFunction.nonUnique2 = nonUniqueSymbol2; ->myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 26, 41)) ->nonUniqueSymbol2 : Symbol(nonUniqueSymbol2, Decl(uniqueSymbolReassignment.ts, 19, 3)) +const symbolName = "this contains symbol but is not one"; +>symbolName : Symbol(symbolName, Decl(uniqueSymbolFullTest.ts, 25, 5)) myFunction.normalVar = normalVar; ->myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 27, 41)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 27, 41)) ->normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 22, 5)) +>myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolFullTest.ts, 25, 57)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolFullTest.ts, 25, 57)) +>normalVar : Symbol(normalVar, Decl(uniqueSymbolFullTest.ts, 24, 5)) myFunction.symbolName = symbolName; ->myFunction.symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 28, 33)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 9, 11), Decl(uniqueSymbolReassignment.ts, 11, 24), Decl(uniqueSymbolReassignment.ts, 14, 39), Decl(uniqueSymbolReassignment.ts, 23, 57), Decl(uniqueSymbolReassignment.ts, 26, 41) ... and 2 more) ->symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 28, 33)) ->symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 23, 5)) - -export { myFunction }; ->myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 31, 8)) +>myFunction.symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolFullTest.ts, 27, 33)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolFullTest.ts, 27, 33)) +>symbolName : Symbol(symbolName, Decl(uniqueSymbolFullTest.ts, 25, 5)) + +// ------------------------- +// Export symbols along with function to test `typeof` behavior +// ------------------------- +export { myFunction, anotherUnique }; +>myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 33, 8)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 33, 20)) diff --git a/tests/baselines/reference/uniqueSymbolReassignment.types b/tests/baselines/reference/uniqueSymbolReassignment.types index 07068bfb3c574..81d01dec09e81 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.types +++ b/tests/baselines/reference/uniqueSymbolReassignment.types @@ -1,7 +1,9 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -=== uniqueSymbolReassignment.ts === -// This is a unique symbol (const + Symbol()) +=== uniqueSymbolFullTest.ts === +// ------------------------- +// Explicit unique symbols (should emit `const` / `typeof` when exported) +// ------------------------- const mySymbol = Symbol('Symbols.mySymbol'); >mySymbol : unique symbol > : ^^^^^^^^^^^^^ @@ -12,20 +14,6 @@ const mySymbol = Symbol('Symbols.mySymbol'); >'Symbols.mySymbol' : "Symbols.mySymbol" > : ^^^^^^^^^^^^^^^^^^ -const Symbols = { ->Symbols : { readonly mySymbol: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ mySymbol} as const : { readonly mySymbol: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ mySymbol} : { readonly mySymbol: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - mySymbol ->mySymbol : unique symbol -> : ^^^^^^^^^^^^^ - -} as const; - const anotherUnique = Symbol('symbols.anotherUnique'); >anotherUnique : unique symbol > : ^^^^^^^^^^^^^ @@ -36,61 +24,41 @@ const anotherUnique = Symbol('symbols.anotherUnique'); >'symbols.anotherUnique' : "symbols.anotherUnique" > : ^^^^^^^^^^^^^^^^^^^^^^^ -const Symbols2 = { ->Symbols2 : { readonly anotherUnique: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ anotherUnique} as const : { readonly anotherUnique: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ anotherUnique} : { readonly anotherUnique: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - anotherUnique ->anotherUnique : unique symbol -> : ^^^^^^^^^^^^^ - -} as const; - function myFunction() {} >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ // Attach the unique ones -myFunction.mySymbol = Symbols.mySymbol; ->myFunction.mySymbol = Symbols.mySymbol : unique symbol -> : ^^^^^^^^^^^^^ +myFunction.mySymbol = mySymbol; +>myFunction.mySymbol = mySymbol : unique symbol +> : ^^^^^^^^^^^^^ >myFunction.mySymbol : unique symbol > : ^^^^^^^^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ >mySymbol : unique symbol > : ^^^^^^^^^^^^^ ->Symbols.mySymbol : unique symbol -> : ^^^^^^^^^^^^^ ->Symbols : { readonly mySymbol: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >mySymbol : unique symbol > : ^^^^^^^^^^^^^ -myFunction.anotherUnique = Symbols2.anotherUnique; ->myFunction.anotherUnique = Symbols2.anotherUnique : unique symbol -> : ^^^^^^^^^^^^^ +myFunction.anotherUnique = anotherUnique; +>myFunction.anotherUnique = anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ >myFunction.anotherUnique : unique symbol > : ^^^^^^^^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ >anotherUnique : unique symbol > : ^^^^^^^^^^^^^ ->Symbols2.anotherUnique : unique symbol -> : ^^^^^^^^^^^^^ ->Symbols2 : { readonly anotherUnique: unique symbol; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >anotherUnique : unique symbol > : ^^^^^^^^^^^^^ -// Non-unique symbols (regular Symbol() without const) -let nonUniqueSymbol1 = Symbol('nonUnique1'); ->nonUniqueSymbol1 : symbol -> : ^^^^^^ +// ------------------------- +// Non-unique symbols (should stay `var`) +// ------------------------- +let nonUnique1 = Symbol('nonUnique1'); +>nonUnique1 : symbol +> : ^^^^^^ >Symbol('nonUnique1') : symbol > : ^^^^^^ >Symbol : SymbolConstructor @@ -98,9 +66,9 @@ let nonUniqueSymbol1 = Symbol('nonUnique1'); >'nonUnique1' : "nonUnique1" > : ^^^^^^^^^^^^ -let nonUniqueSymbol2 = Symbol('nonUnique2'); ->nonUniqueSymbol2 : symbol -> : ^^^^^^ +let nonUnique2 = Symbol('nonUnique2'); +>nonUnique2 : symbol +> : ^^^^^^ >Symbol('nonUnique2') : symbol > : ^^^^^^ >Symbol : SymbolConstructor @@ -108,55 +76,56 @@ let nonUniqueSymbol2 = Symbol('nonUnique2'); >'nonUnique2' : "nonUnique2" > : ^^^^^^^^^^^^ -// Plain text variables (not symbols at all) -const normalVar = "not a symbol"; ->normalVar : "not a symbol" -> : ^^^^^^^^^^^^^^ ->"not a symbol" : "not a symbol" -> : ^^^^^^^^^^^^^^ - -const symbolName = "this contains symbol but is not one"; ->symbolName : "this contains symbol but is not one" -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"this contains symbol but is not one" : "this contains symbol but is not one" -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -// Attach those as well -myFunction.nonUnique1 = nonUniqueSymbol1; ->myFunction.nonUnique1 = nonUniqueSymbol1 : symbol -> : ^^^^^^ +myFunction.nonUnique1 = nonUnique1; +>myFunction.nonUnique1 = nonUnique1 : symbol +> : ^^^^^^ >myFunction.nonUnique1 : symbol > : ^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ >nonUnique1 : symbol > : ^^^^^^ ->nonUniqueSymbol1 : symbol -> : ^^^^^^ +>nonUnique1 : symbol +> : ^^^^^^ -myFunction.nonUnique2 = nonUniqueSymbol2; ->myFunction.nonUnique2 = nonUniqueSymbol2 : symbol -> : ^^^^^^ +myFunction.nonUnique2 = nonUnique2; +>myFunction.nonUnique2 = nonUnique2 : symbol +> : ^^^^^^ >myFunction.nonUnique2 : symbol > : ^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ >nonUnique2 : symbol > : ^^^^^^ ->nonUniqueSymbol2 : symbol -> : ^^^^^^ +>nonUnique2 : symbol +> : ^^^^^^ + +// ------------------------- +// Normal variables (should stay `var`/string) +// ------------------------- +const normalVar = "just a string"; +>normalVar : "just a string" +> : ^^^^^^^^^^^^^^^ +>"just a string" : "just a string" +> : ^^^^^^^^^^^^^^^ + +const symbolName = "this contains symbol but is not one"; +>symbolName : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"this contains symbol but is not one" : "this contains symbol but is not one" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ myFunction.normalVar = normalVar; ->myFunction.normalVar = normalVar : "not a symbol" -> : ^^^^^^^^^^^^^^ +>myFunction.normalVar = normalVar : "just a string" +> : ^^^^^^^^^^^^^^^ >myFunction.normalVar : string > : ^^^^^^ >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ >normalVar : string > : ^^^^^^ ->normalVar : "not a symbol" -> : ^^^^^^^^^^^^^^ +>normalVar : "just a string" +> : ^^^^^^^^^^^^^^^ myFunction.symbolName = symbolName; >myFunction.symbolName = symbolName : "this contains symbol but is not one" @@ -170,7 +139,12 @@ myFunction.symbolName = symbolName; >symbolName : "this contains symbol but is not one" > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -export { myFunction }; +// ------------------------- +// Export symbols along with function to test `typeof` behavior +// ------------------------- +export { myFunction, anotherUnique }; >myFunction : typeof myFunction > : ^^^^^^^^^^^^^^^^^ +>anotherUnique : unique symbol +> : ^^^^^^^^^^^^^ diff --git a/tests/cases/compiler/uniqueSymbolReassignment.ts b/tests/cases/compiler/uniqueSymbolReassignment.ts index 041387c4b2cd7..b71673ceec158 100644 --- a/tests/cases/compiler/uniqueSymbolReassignment.ts +++ b/tests/cases/compiler/uniqueSymbolReassignment.ts @@ -1,35 +1,38 @@ -// @filename: uniqueSymbolReassignment.ts +// @filename: uniqueSymbolFullTest.ts // @declaration: true // @lib: esnext -// This is a unique symbol (const + Symbol()) -const mySymbol = Symbol('Symbols.mySymbol'); -const Symbols = { - mySymbol -} as const; +// ------------------------- +// Explicit unique symbols (should emit `const` / `typeof` when exported) +// ------------------------- +const mySymbol = Symbol('Symbols.mySymbol'); const anotherUnique = Symbol('symbols.anotherUnique'); -const Symbols2 = { - anotherUnique -} as const; function myFunction() {} // Attach the unique ones -myFunction.mySymbol = Symbols.mySymbol; -myFunction.anotherUnique = Symbols2.anotherUnique; +myFunction.mySymbol = mySymbol; +myFunction.anotherUnique = anotherUnique; + +// ------------------------- +// Non-unique symbols (should stay `var`) +// ------------------------- +let nonUnique1 = Symbol('nonUnique1'); +let nonUnique2 = Symbol('nonUnique2'); -// Non-unique symbols (regular Symbol() without const) -let nonUniqueSymbol1 = Symbol('nonUnique1'); -let nonUniqueSymbol2 = Symbol('nonUnique2'); +myFunction.nonUnique1 = nonUnique1; +myFunction.nonUnique2 = nonUnique2; -// Plain text variables (not symbols at all) -const normalVar = "not a symbol"; +// ------------------------- +// Normal variables (should stay `var`/string) +// ------------------------- +const normalVar = "just a string"; const symbolName = "this contains symbol but is not one"; -// Attach those as well -myFunction.nonUnique1 = nonUniqueSymbol1; -myFunction.nonUnique2 = nonUniqueSymbol2; myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -export { myFunction }; \ No newline at end of file +// ------------------------- +// Export symbols along with function to test `typeof` behavior +// ------------------------- +export { myFunction, anotherUnique }; From 294e6cbb4849f81f7ded103fbd6d95d1a5858b9b Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 30 Sep 2025 00:02:15 +0530 Subject: [PATCH 09/11] fix(tests): correct @filename header in unique symbol test --- tests/cases/compiler/uniqueSymbolReassignment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/compiler/uniqueSymbolReassignment.ts b/tests/cases/compiler/uniqueSymbolReassignment.ts index b71673ceec158..48618096e90b9 100644 --- a/tests/cases/compiler/uniqueSymbolReassignment.ts +++ b/tests/cases/compiler/uniqueSymbolReassignment.ts @@ -1,4 +1,4 @@ -// @filename: uniqueSymbolFullTest.ts +// @filename: uniqueSymbolReassignment.ts // @declaration: true // @lib: esnext From 89a0bf673855fc9a35d4bad6a7cb2dbd302c2489 Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 30 Sep 2025 00:05:19 +0530 Subject: [PATCH 10/11] format(declarations): fix formatting --- src/compiler/transformers/declarations.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index e01e0f16eda8e..62e0d1a958b27 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -217,8 +217,12 @@ import { visitNodes, VisitResult, } from "../_namespaces/ts.js"; +import { + idText, + isIdentifier, + PrivateIdentifier, +} from "../_namespaces/ts.js"; import { collectExternalModuleInfo } from "./utilities.js"; -import { PrivateIdentifier, isIdentifier, idText } from "../_namespaces/ts.js"; /** @internal */ export function getDeclarationDiagnostics( host: EmitHost, @@ -1464,15 +1468,15 @@ export function transformDeclarations(context: TransformationContext): Transform fakespace.locals = createSymbolTable(props); fakespace.symbol = props[0].parent!; const exportMappings: [Identifier, string][] = []; - + // Before emitting expando properties, get all exported names for the file const moduleInfo = collectExternalModuleInfo(context, input.parent as SourceFile); const topLevelExportNames = new Set( (moduleInfo.exportedNames ?? []) .filter(n => isIdentifier(n) || isPrivateIdentifier(n)) - .map(n => idText(n as Identifier | PrivateIdentifier)) + .map(n => idText(n as Identifier | PrivateIdentifier)), ); - + let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => { if (!isExpandoPropertyDeclaration(p.valueDeclaration)) { return undefined; From 16dfb5ad168c7f56c5edf7483397c033c35372ff Mon Sep 17 00:00:00 2001 From: Akshit222 Date: Tue, 30 Sep 2025 17:31:17 +0530 Subject: [PATCH 11/11] Update baselines for uniqueSymbolReassignment test (unique symbol typeof emission) --- .../reference/uniqueSymbolReassignment.js | 10 +-- .../uniqueSymbolReassignment.symbols | 68 +++++++++---------- .../reference/uniqueSymbolReassignment.types | 2 +- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/baselines/reference/uniqueSymbolReassignment.js b/tests/baselines/reference/uniqueSymbolReassignment.js index 8f77cbaac9566..5a0cfcc01afde 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.js +++ b/tests/baselines/reference/uniqueSymbolReassignment.js @@ -1,6 +1,6 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -//// [uniqueSymbolFullTest.ts] +//// [uniqueSymbolReassignment.ts] // ------------------------- // Explicit unique symbols (should emit `const` / `typeof` when exported) // ------------------------- @@ -37,7 +37,7 @@ myFunction.symbolName = symbolName; export { myFunction, anotherUnique }; -//// [uniqueSymbolFullTest.js] +//// [uniqueSymbolReassignment.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.anotherUnique = void 0; @@ -68,7 +68,7 @@ myFunction.normalVar = normalVar; myFunction.symbolName = symbolName; -//// [uniqueSymbolFullTest.d.ts] +//// [uniqueSymbolReassignment.d.ts] declare const anotherUnique: unique symbol; declare function myFunction(): void; declare namespace myFunction { @@ -85,10 +85,10 @@ export { myFunction, anotherUnique }; //// [DtsFileErrors] -uniqueSymbolFullTest.d.ts(5,11): error TS2502: 'anotherUnique' is referenced directly or indirectly in its own type annotation. +uniqueSymbolReassignment.d.ts(5,11): error TS2502: 'anotherUnique' is referenced directly or indirectly in its own type annotation. -==== uniqueSymbolFullTest.d.ts (1 errors) ==== +==== uniqueSymbolReassignment.d.ts (1 errors) ==== declare const anotherUnique: unique symbol; declare function myFunction(): void; declare namespace myFunction { diff --git a/tests/baselines/reference/uniqueSymbolReassignment.symbols b/tests/baselines/reference/uniqueSymbolReassignment.symbols index a721d2d339f13..bd56f3a7ffd90 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.symbols +++ b/tests/baselines/reference/uniqueSymbolReassignment.symbols @@ -1,81 +1,81 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -=== uniqueSymbolFullTest.ts === +=== uniqueSymbolReassignment.ts === // ------------------------- // Explicit unique symbols (should emit `const` / `typeof` when exported) // ------------------------- const mySymbol = Symbol('Symbols.mySymbol'); ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolFullTest.ts, 3, 5)) +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 3, 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 anotherUnique = Symbol('symbols.anotherUnique'); ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 4, 5)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 4, 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, --, --)) function myFunction() {} ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) // Attach the unique ones myFunction.mySymbol = mySymbol; ->myFunction.mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolFullTest.ts, 6, 24)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolFullTest.ts, 6, 24)) ->mySymbol : Symbol(mySymbol, Decl(uniqueSymbolFullTest.ts, 3, 5)) +>myFunction.mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 6, 24)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>mySymbol : Symbol(myFunction.mySymbol, Decl(uniqueSymbolReassignment.ts, 6, 24)) +>mySymbol : Symbol(mySymbol, Decl(uniqueSymbolReassignment.ts, 3, 5)) myFunction.anotherUnique = anotherUnique; ->myFunction.anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolFullTest.ts, 9, 31)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolFullTest.ts, 9, 31)) ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 4, 5)) +>myFunction.anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 9, 31)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>anotherUnique : Symbol(myFunction.anotherUnique, Decl(uniqueSymbolReassignment.ts, 9, 31)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 4, 5)) // ------------------------- // Non-unique symbols (should stay `var`) // ------------------------- let nonUnique1 = Symbol('nonUnique1'); ->nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolFullTest.ts, 15, 3)) +>nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolReassignment.ts, 15, 3)) >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, --, --)) let nonUnique2 = Symbol('nonUnique2'); ->nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolFullTest.ts, 16, 3)) +>nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolReassignment.ts, 16, 3)) >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, --, --)) myFunction.nonUnique1 = nonUnique1; ->myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolFullTest.ts, 16, 38)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolFullTest.ts, 16, 38)) ->nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolFullTest.ts, 15, 3)) +>myFunction.nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 16, 38)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>nonUnique1 : Symbol(myFunction.nonUnique1, Decl(uniqueSymbolReassignment.ts, 16, 38)) +>nonUnique1 : Symbol(nonUnique1, Decl(uniqueSymbolReassignment.ts, 15, 3)) myFunction.nonUnique2 = nonUnique2; ->myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolFullTest.ts, 18, 35)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolFullTest.ts, 18, 35)) ->nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolFullTest.ts, 16, 3)) +>myFunction.nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 18, 35)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>nonUnique2 : Symbol(myFunction.nonUnique2, Decl(uniqueSymbolReassignment.ts, 18, 35)) +>nonUnique2 : Symbol(nonUnique2, Decl(uniqueSymbolReassignment.ts, 16, 3)) // ------------------------- // Normal variables (should stay `var`/string) // ------------------------- const normalVar = "just a string"; ->normalVar : Symbol(normalVar, Decl(uniqueSymbolFullTest.ts, 24, 5)) +>normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 24, 5)) const symbolName = "this contains symbol but is not one"; ->symbolName : Symbol(symbolName, Decl(uniqueSymbolFullTest.ts, 25, 5)) +>symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 25, 5)) myFunction.normalVar = normalVar; ->myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolFullTest.ts, 25, 57)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolFullTest.ts, 25, 57)) ->normalVar : Symbol(normalVar, Decl(uniqueSymbolFullTest.ts, 24, 5)) +>myFunction.normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 25, 57)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>normalVar : Symbol(myFunction.normalVar, Decl(uniqueSymbolReassignment.ts, 25, 57)) +>normalVar : Symbol(normalVar, Decl(uniqueSymbolReassignment.ts, 24, 5)) myFunction.symbolName = symbolName; ->myFunction.symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolFullTest.ts, 27, 33)) ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 4, 54), Decl(uniqueSymbolFullTest.ts, 6, 24), Decl(uniqueSymbolFullTest.ts, 9, 31), Decl(uniqueSymbolFullTest.ts, 16, 38), Decl(uniqueSymbolFullTest.ts, 18, 35) ... and 2 more) ->symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolFullTest.ts, 27, 33)) ->symbolName : Symbol(symbolName, Decl(uniqueSymbolFullTest.ts, 25, 5)) +>myFunction.symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 27, 33)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 4, 54), Decl(uniqueSymbolReassignment.ts, 6, 24), Decl(uniqueSymbolReassignment.ts, 9, 31), Decl(uniqueSymbolReassignment.ts, 16, 38), Decl(uniqueSymbolReassignment.ts, 18, 35) ... and 2 more) +>symbolName : Symbol(myFunction.symbolName, Decl(uniqueSymbolReassignment.ts, 27, 33)) +>symbolName : Symbol(symbolName, Decl(uniqueSymbolReassignment.ts, 25, 5)) // ------------------------- // Export symbols along with function to test `typeof` behavior // ------------------------- export { myFunction, anotherUnique }; ->myFunction : Symbol(myFunction, Decl(uniqueSymbolFullTest.ts, 33, 8)) ->anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolFullTest.ts, 33, 20)) +>myFunction : Symbol(myFunction, Decl(uniqueSymbolReassignment.ts, 33, 8)) +>anotherUnique : Symbol(anotherUnique, Decl(uniqueSymbolReassignment.ts, 33, 20)) diff --git a/tests/baselines/reference/uniqueSymbolReassignment.types b/tests/baselines/reference/uniqueSymbolReassignment.types index 81d01dec09e81..81ac76dabdfa6 100644 --- a/tests/baselines/reference/uniqueSymbolReassignment.types +++ b/tests/baselines/reference/uniqueSymbolReassignment.types @@ -1,6 +1,6 @@ //// [tests/cases/compiler/uniqueSymbolReassignment.ts] //// -=== uniqueSymbolFullTest.ts === +=== uniqueSymbolReassignment.ts === // ------------------------- // Explicit unique symbols (should emit `const` / `typeof` when exported) // -------------------------