Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/compiler/transformers/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ import {
tryCast,
TypeAliasDeclaration,
TypeNode,
TypeOperatorNode,
TypeParameterDeclaration,
TypeReferenceNode,
unescapeLeadingUnderscores,
Expand Down Expand Up @@ -1479,7 +1480,10 @@ 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 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));
Expand Down Expand Up @@ -1817,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);
}
Expand Down
48 changes: 48 additions & 0 deletions tests/baselines/reference/uniqueSymbolReassignment.errors.txt
Original file line number Diff line number Diff line change
@@ -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 };

65 changes: 65 additions & 0 deletions tests/baselines/reference/uniqueSymbolReassignment.js
Original file line number Diff line number Diff line change
@@ -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;
90 changes: 90 additions & 0 deletions tests/baselines/reference/uniqueSymbolReassignment.symbols
Original file line number Diff line number Diff line change
@@ -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))

Loading
Loading