@@ -898,6 +898,7 @@ namespace ts {
898898 // This allows users to just specify library files they want to used through --lib
899899 // and they will not get an error from not having unrelated library files
900900 let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined;
901+ let deferredGlobalESSymbolConstructorTypeSymbol: Symbol | undefined;
901902 let deferredGlobalESSymbolType: ObjectType;
902903 let deferredGlobalTypedPropertyDescriptorType: GenericType;
903904 let deferredGlobalPromiseType: GenericType;
@@ -3677,11 +3678,30 @@ namespace ts {
36773678 const additionalContainers = mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer);
36783679 const reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration);
36793680 const objectLiteralContainer = getVariableDeclarationOfObjectLiteral(container, meaning);
3680- if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, SymbolFlags.Namespace, /*externalOnly*/ false)) {
3681+ if (
3682+ enclosingDeclaration &&
3683+ container.flags & getQualifiedLeftMeaning(meaning) &&
3684+ getAccessibleSymbolChain(container, enclosingDeclaration, SymbolFlags.Namespace, /*externalOnly*/ false)
3685+ ) {
36813686 return append(concatenate(concatenate([container], additionalContainers), reexportContainers), objectLiteralContainer); // This order expresses a preference for the real container if it is in scope
36823687 }
3683- const res = append(append(additionalContainers, container), objectLiteralContainer);
3684- return concatenate(res, reexportContainers);
3688+ // we potentially have a symbol which is a member of the instance side of something - look for a variable in scope with the container's type
3689+ // which may be acting like a namespace (eg, `Symbol` acts like a namespace when looking up `Symbol.toStringTag`)
3690+ const firstVariableMatch = !(container.flags & getQualifiedLeftMeaning(meaning))
3691+ && container.flags & SymbolFlags.Type
3692+ && getDeclaredTypeOfSymbol(container).flags & TypeFlags.Object
3693+ && meaning === SymbolFlags.Value
3694+ ? forEachSymbolTableInScope(enclosingDeclaration, t => {
3695+ return forEachEntry(t, s => {
3696+ if (s.flags & getQualifiedLeftMeaning(meaning) && getTypeOfSymbol(s) === getDeclaredTypeOfSymbol(container)) {
3697+ return s;
3698+ }
3699+ });
3700+ }) : undefined;
3701+ let res = firstVariableMatch ? [firstVariableMatch, ...additionalContainers, container] : [...additionalContainers, container];
3702+ res = append(res, objectLiteralContainer);
3703+ res = addRange(res, reexportContainers);
3704+ return res;
36853705 }
36863706 const candidates = mapDefined(symbol.declarations, d => {
36873707 if (!isAmbientModule(d) && d.parent && hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) {
@@ -5107,8 +5127,9 @@ namespace ts {
51075127 }
51085128 }
51095129 }
5110- context.enclosingDeclaration = saveEnclosingDeclaration;
5130+ context.enclosingDeclaration = propertySymbol.valueDeclaration || propertySymbol.declarations?.[0] || saveEnclosingDeclaration;
51115131 const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context);
5132+ context.enclosingDeclaration = saveEnclosingDeclaration;
51125133 context.approximateLength += (symbolName(propertySymbol).length + 1);
51135134 const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined;
51145135 if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
@@ -5852,9 +5873,6 @@ namespace ts {
58525873 if (fromNameType) {
58535874 return fromNameType;
58545875 }
5855- if (isKnownSymbol(symbol)) {
5856- return factory.createComputedPropertyName(factory.createPropertyAccessExpression(factory.createIdentifier("Symbol"), (symbol.escapedName as string).substr(3)));
5857- }
58585876 const rawName = unescapeLeadingUnderscores(symbol.escapedName);
58595877 const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed);
58605878 return createPropertyNameNodeForIdentifierOrLiteral(rawName, stringNamed, singleQuote);
@@ -8707,8 +8725,18 @@ namespace ts {
87078725 return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true), declaration, reportErrors);
87088726 }
87098727
8728+ function isGlobalSymbolConstructor(node: Node) {
8729+ const symbol = getSymbolOfNode(node);
8730+ const globalSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false);
8731+ return globalSymbol && symbol && symbol === globalSymbol;
8732+ }
8733+
87108734 function widenTypeForVariableLikeDeclaration(type: Type | undefined, declaration: any, reportErrors?: boolean) {
87118735 if (type) {
8736+ // TODO: If back compat with pre-3.0/4.0 libs isn't required, remove the following SymbolConstructor special case transforming `symbol` into `unique symbol`
8737+ if (type.flags & TypeFlags.ESSymbol && isGlobalSymbolConstructor(declaration.parent)) {
8738+ type = getESSymbolLikeTypeForNode(declaration);
8739+ }
87128740 if (reportErrors) {
87138741 reportErrorsFromWidening(declaration, type);
87148742 }
@@ -12859,6 +12887,10 @@ namespace ts {
1285912887 return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors));
1286012888 }
1286112889
12890+ function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean) {
12891+ return deferredGlobalESSymbolConstructorTypeSymbol || (deferredGlobalESSymbolConstructorTypeSymbol = getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors));
12892+ }
12893+
1286212894 function getGlobalESSymbolType(reportErrors: boolean) {
1286312895 return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
1286412896 }
@@ -13941,13 +13973,13 @@ namespace ts {
1394113973 function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags) {
1394213974 if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
1394313975 let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType;
13944- if (!type && !isKnownSymbol(prop) ) {
13976+ if (!type) {
1394513977 if (prop.escapedName === InternalSymbolName.Default) {
1394613978 type = getLiteralType("default");
1394713979 }
1394813980 else {
1394913981 const name = prop.valueDeclaration && getNameOfDeclaration(prop.valueDeclaration) as PropertyName;
13950- type = name && getLiteralTypeFromPropertyName(name) || getLiteralType(symbolName(prop));
13982+ type = name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getLiteralType(symbolName(prop)) : undefined );
1395113983 }
1395213984 }
1395313985 if (type && type.flags & include) {
@@ -14174,11 +14206,8 @@ namespace ts {
1417414206 }
1417514207
1417614208 function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | PrivateIdentifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
14177- const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
1417814209 return isTypeUsableAsPropertyName(indexType) ?
1417914210 getPropertyNameFromType(indexType) :
14180- accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
14181- getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
1418214211 accessNode && isPropertyName(accessNode) ?
1418314212 // late bound names are handled in the first branch, so here we only need to handle normal names
1418414213 getPropertyNameForPropertyNameNode(accessNode) :
@@ -25279,9 +25308,6 @@ namespace ts {
2527925308 !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) {
2528025309 error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
2528125310 }
25282- else {
25283- checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
25284- }
2528525311 }
2528625312
2528725313 return links.resolvedType;
@@ -25342,15 +25368,15 @@ namespace ts {
2534225368 // As otherwise they may not be checked until exports for the type at this position are retrieved,
2534325369 // which may never occur.
2534425370 for (const elem of node.properties) {
25345- if (elem.name && isComputedPropertyName(elem.name) && !isWellKnownSymbolSyntactically(elem.name) ) {
25371+ if (elem.name && isComputedPropertyName(elem.name)) {
2534625372 checkComputedPropertyName(elem.name);
2534725373 }
2534825374 }
2534925375
2535025376 let offset = 0;
2535125377 for (const memberDecl of node.properties) {
2535225378 let member = getSymbolOfNode(memberDecl);
25353- const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
25379+ const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName ?
2535425380 checkComputedPropertyName(memberDecl.name) : undefined;
2535525381 if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
2535625382 memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
@@ -27006,48 +27032,6 @@ namespace ts {
2700627032 return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
2700727033 }
2700827034
27009- function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
27010- if (expressionType === errorType) {
27011- // There is already an error, so no need to report one.
27012- return false;
27013- }
27014-
27015- if (!isWellKnownSymbolSyntactically(expression)) {
27016- return false;
27017- }
27018-
27019- // Make sure the property type is the primitive symbol type
27020- if ((expressionType.flags & TypeFlags.ESSymbolLike) === 0) {
27021- if (reportError) {
27022- error(expression, Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, getTextOfNode(expression));
27023- }
27024- return false;
27025- }
27026-
27027- // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
27028- // global Symbol object
27029- const leftHandSide = <Identifier>(<PropertyAccessExpression>expression).expression;
27030- const leftHandSideSymbol = getResolvedSymbol(leftHandSide);
27031- if (!leftHandSideSymbol) {
27032- return false;
27033- }
27034-
27035- const globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
27036- if (!globalESSymbol) {
27037- // Already errored when we tried to look up the symbol
27038- return false;
27039- }
27040-
27041- if (leftHandSideSymbol !== globalESSymbol) {
27042- if (reportError) {
27043- error(leftHandSide, Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
27044- }
27045- return false;
27046- }
27047-
27048- return true;
27049- }
27050-
2705127035 function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement {
2705227036 return isCallOrNewExpression(node) || isTaggedTemplateExpression(node) || isJsxOpeningLikeElement(node);
2705327037 }
@@ -35355,6 +35339,12 @@ namespace ts {
3535535339 }
3535635340 }
3535735341
35342+ function getPropertyNameForKnownSymbolName(symbolName: string): __String {
35343+ const ctorType = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false);
35344+ const uniqueType = ctorType && getTypeOfPropertyOfType(getTypeOfSymbol(ctorType), escapeLeadingUnderscores(symbolName));
35345+ return uniqueType && isTypeUsableAsPropertyName(uniqueType) ? getPropertyNameFromType(uniqueType) : `__@${symbolName}` as __String;
35346+ }
35347+
3535835348 /**
3535935349 * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
3536035350 * type from its members.
0 commit comments