diff --git a/packages/typescript/src/enums/typeFlags.enum.ts b/packages/typescript/src/enums/typeFlags.enum.ts index 282cbcfe49406..ead524eb1eb51 100644 --- a/packages/typescript/src/enums/typeFlags.enum.ts +++ b/packages/typescript/src/enums/typeFlags.enum.ts @@ -33,7 +33,7 @@ export enum TypeFlags { Intersection = 1 << 28, Reserved1 = 1 << 29, Reserved2 = 1 << 30, - Reserved3 = 1 << 31, + RegisteredESSymbol = 1 << 31, AnyOrUnknown = Any | Unknown, Nullable = Undefined | Null, Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral, @@ -49,7 +49,7 @@ export enum TypeFlags { BigIntLike = BigInt | BigIntLiteral, BooleanLike = Boolean | BooleanLiteral, EnumLike = Enum | EnumLiteral, - ESSymbolLike = ESSymbol | UniqueESSymbol, + ESSymbolLike = ESSymbol | UniqueESSymbol | RegisteredESSymbol, VoidLike = Void | Undefined, Primitive = StringLike | NumberLike | BigIntLike | BooleanLike | EnumLike | ESSymbolLike | VoidLike | Null, DefinitelyNonNullable = StringLike | NumberLike | BigIntLike | BooleanLike | EnumLike | ESSymbolLike | Object | NonPrimitive, @@ -58,13 +58,13 @@ export enum TypeFlags { StructuredType = Object | Union | Intersection, TypeVariable = TypeParameter | IndexedAccess, InstantiableNonPrimitive = TypeVariable | Conditional | Substitution, - InstantiablePrimitive = Index | TemplateLiteral | StringMapping, + InstantiablePrimitive = Index | TemplateLiteral | StringMapping | RegisteredESSymbol, Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, StructuredOrInstantiable = StructuredType | Instantiable, ObjectFlagsType = Any | Nullable | Never | Object | Union | Intersection, Simplifiable = IndexedAccess | Conditional | Index, Singleton = Any | Unknown | String | Number | Boolean | BigInt | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, - Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, + Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbolLike | NonPrimitive, IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral | StringMapping, IncludesMissingType = TypeParameter, IncludesNonWideningType = Index, diff --git a/packages/typescript/src/enums/typeFlags.ts b/packages/typescript/src/enums/typeFlags.ts index e1e8432972020..cb68e6e3f5527 100644 --- a/packages/typescript/src/enums/typeFlags.ts +++ b/packages/typescript/src/enums/typeFlags.ts @@ -33,7 +33,7 @@ export var TypeFlags: any; TypeFlags[TypeFlags["Intersection"] = 268435456] = "Intersection"; TypeFlags[TypeFlags["Reserved1"] = 536870912] = "Reserved1"; TypeFlags[TypeFlags["Reserved2"] = 1073741824] = "Reserved2"; - TypeFlags[TypeFlags["Reserved3"] = -2147483648] = "Reserved3"; + TypeFlags[TypeFlags["RegisteredESSymbol"] = -2147483648] = "RegisteredESSymbol"; TypeFlags[TypeFlags["AnyOrUnknown"] = 3] = "AnyOrUnknown"; TypeFlags[TypeFlags["Nullable"] = 12] = "Nullable"; TypeFlags[TypeFlags["Literal"] = 15360] = "Literal"; @@ -49,23 +49,23 @@ export var TypeFlags: any; TypeFlags[TypeFlags["BigIntLike"] = 4224] = "BigIntLike"; TypeFlags[TypeFlags["BooleanLike"] = 8448] = "BooleanLike"; TypeFlags[TypeFlags["EnumLike"] = 98304] = "EnumLike"; - TypeFlags[TypeFlags["ESSymbolLike"] = 16896] = "ESSymbolLike"; + TypeFlags[TypeFlags["ESSymbolLike"] = -2147466752] = "ESSymbolLike"; TypeFlags[TypeFlags["VoidLike"] = 20] = "VoidLike"; - TypeFlags[TypeFlags["Primitive"] = 12713980] = "Primitive"; - TypeFlags[TypeFlags["DefinitelyNonNullable"] = 13893600] = "DefinitelyNonNullable"; - TypeFlags[TypeFlags["DisjointDomains"] = 12812284] = "DisjointDomains"; + TypeFlags[TypeFlags["Primitive"] = -2134769668] = "Primitive"; + TypeFlags[TypeFlags["DefinitelyNonNullable"] = -2133590048] = "DefinitelyNonNullable"; + TypeFlags[TypeFlags["DisjointDomains"] = -2134671364] = "DisjointDomains"; TypeFlags[TypeFlags["UnionOrIntersection"] = 402653184] = "UnionOrIntersection"; TypeFlags[TypeFlags["StructuredType"] = 403701760] = "StructuredType"; TypeFlags[TypeFlags["TypeVariable"] = 34078720] = "TypeVariable"; TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 117964800] = "InstantiableNonPrimitive"; - TypeFlags[TypeFlags["InstantiablePrimitive"] = 14680064] = "InstantiablePrimitive"; - TypeFlags[TypeFlags["Instantiable"] = 132644864] = "Instantiable"; - TypeFlags[TypeFlags["StructuredOrInstantiable"] = 536346624] = "StructuredOrInstantiable"; + TypeFlags[TypeFlags["InstantiablePrimitive"] = -2132803584] = "InstantiablePrimitive"; + TypeFlags[TypeFlags["Instantiable"] = -2014838784] = "Instantiable"; + TypeFlags[TypeFlags["StructuredOrInstantiable"] = -1611137024] = "StructuredOrInstantiable"; TypeFlags[TypeFlags["ObjectFlagsType"] = 403963917] = "ObjectFlagsType"; TypeFlags[TypeFlags["Simplifiable"] = 102760448] = "Simplifiable"; TypeFlags[TypeFlags["Singleton"] = 394239] = "Singleton"; - TypeFlags[TypeFlags["Narrowable"] = 536575971] = "Narrowable"; - TypeFlags[TypeFlags["IncludesMask"] = 416808959] = "IncludesMask"; + TypeFlags[TypeFlags["Narrowable"] = -1610907677] = "Narrowable"; + TypeFlags[TypeFlags["IncludesMask"] = -1730674689] = "IncludesMask"; TypeFlags[TypeFlags["IncludesMissingType"] = 524288] = "IncludesMissingType"; TypeFlags[TypeFlags["IncludesNonWideningType"] = 2097152] = "IncludesNonWideningType"; TypeFlags[TypeFlags["IncludesWildcard"] = 33554432] = "IncludesWildcard"; diff --git a/tsc/internal/api/enum_values_generated.go b/tsc/internal/api/enum_values_generated.go index d1f15a1830af3..0739c44a2d0d9 100644 --- a/tsc/internal/api/enum_values_generated.go +++ b/tsc/internal/api/enum_values_generated.go @@ -159,7 +159,7 @@ func main() { "Intersection": toInt32(checker.TypeFlagsIntersection), "Reserved1": toInt32(checker.TypeFlagsReserved1), "Reserved2": toInt32(checker.TypeFlagsReserved2), - "Reserved3": toInt32(checker.TypeFlagsReserved3), + "RegisteredESSymbol": toInt32(checker.TypeFlagsRegisteredESSymbol), "AnyOrUnknown": toInt32(checker.TypeFlagsAnyOrUnknown), "Nullable": toInt32(checker.TypeFlagsNullable), "Literal": toInt32(checker.TypeFlagsLiteral), diff --git a/tsc/internal/bundled/libs/lib.es2015.symbol.d.ts b/tsc/internal/bundled/libs/lib.es2015.symbol.d.ts index b2ba22dba66fa..36f295fe2874a 100644 --- a/tsc/internal/bundled/libs/lib.es2015.symbol.d.ts +++ b/tsc/internal/bundled/libs/lib.es2015.symbol.d.ts @@ -31,7 +31,7 @@ interface SymbolConstructor { * Otherwise, returns a new symbol with this key. * @param key key to search for. */ - for(key: string): symbol; + for(key: Key): RegisteredSymbol; /** * Returns a key from the global symbol registry matching the given Symbol if found. @@ -42,3 +42,5 @@ interface SymbolConstructor { } declare var Symbol: SymbolConstructor; + +type RegisteredSymbol = intrinsic; diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 983fc751b03f8..90ba7825238a7 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -356,14 +356,16 @@ const ( IntrinsicTypeKindCapitalize IntrinsicTypeKindUncapitalize IntrinsicTypeKindNoInfer + IntrinsicTypeKindRegisteredSymbol ) var intrinsicTypeKinds = map[string]IntrinsicTypeKind{ - "Uppercase": IntrinsicTypeKindUppercase, - "Lowercase": IntrinsicTypeKindLowercase, - "Capitalize": IntrinsicTypeKindCapitalize, - "Uncapitalize": IntrinsicTypeKindUncapitalize, - "NoInfer": IntrinsicTypeKindNoInfer, + "Uppercase": IntrinsicTypeKindUppercase, + "Lowercase": IntrinsicTypeKindLowercase, + "Capitalize": IntrinsicTypeKindCapitalize, + "Uncapitalize": IntrinsicTypeKindUncapitalize, + "NoInfer": IntrinsicTypeKindNoInfer, + "RegisteredSymbol": IntrinsicTypeKindRegisteredSymbol, } type MappedTypeModifiers uint32 @@ -631,6 +633,7 @@ type Checker struct { indexedAccessTypes map[CacheHashKey]*Type templateLiteralTypes map[CacheHashKey]*Type stringMappingTypes map[StringMappingKey]*Type + registeredESSymbolTypes map[CacheHashKey]*Type uniqueESSymbolTypes map[*ast.Symbol]*Type thisExpandoKinds map[*ast.Symbol]thisAssignmentDeclarationKind thisExpandoLocations map[*ast.Symbol]*ast.Node @@ -947,6 +950,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) { c.indexedAccessTypes = make(map[CacheHashKey]*Type) c.templateLiteralTypes = make(map[CacheHashKey]*Type) c.stringMappingTypes = make(map[StringMappingKey]*Type) + c.registeredESSymbolTypes = make(map[CacheHashKey]*Type) c.uniqueESSymbolTypes = make(map[*ast.Symbol]*Type) c.thisExpandoKinds = make(map[*ast.Symbol]thisAssignmentDeclarationKind) c.thisExpandoLocations = make(map[*ast.Symbol]*ast.Node) @@ -7539,7 +7543,7 @@ func (c *Checker) getQuickTypeOfExpression(node *ast.Node) *Type { return nil // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - case ast.IsCallExpression(expr) && expr.Expression().Kind != ast.KindSuperKeyword && !ast.IsRequireCall(expr, true /*requireStringLiteralLikeArgument*/) && !c.isSymbolOrSymbolForCall(expr) && !ast.IsImportCall(expr): + case ast.IsCallExpression(expr) && expr.Expression().Kind != ast.KindSuperKeyword && !ast.IsRequireCall(expr, true /*requireStringLiteralLikeArgument*/) && !c.isSymbolCall(expr) && !ast.IsImportCall(expr): if isCallChain(expr) { return c.getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) } @@ -8519,7 +8523,7 @@ func (c *Checker) checkCallExpression(node *ast.Node, checkMode CheckMode) *Type returnType := c.getReturnTypeOfSignature(signature) // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property // as a fresh unique symbol literal type. - if returnType.flags&TypeFlagsESSymbolLike != 0 && c.isSymbolOrSymbolForCall(node) { + if returnType.flags&TypeFlagsESSymbolLike != 0 && c.isSymbolCall(node) { return c.getESSymbolLikeTypeForNode(ast.WalkUpParenthesizedExpressions(node.Parent)) } if ast.IsCallExpression(node) && node.QuestionDotToken() == nil && ast.IsExpressionStatement(node.Parent) && returnType.flags&TypeFlagsVoid != 0 && c.getTypePredicateOfSignature(signature) != nil { @@ -8550,14 +8554,11 @@ func (c *Checker) addDeprecatedSuggestionWithSignature(location *ast.Node, decla return c.addDeprecatedSuggestionWorker([]*ast.Node{declaration}, diagnostic) } -func (c *Checker) isSymbolOrSymbolForCall(node *ast.Node) bool { +func (c *Checker) isSymbolCall(node *ast.Node) bool { if !ast.IsCallExpression(node) { return false } left := node.Expression() - if ast.IsPropertyAccessExpression(left) && left.Name().Text() == "for" { - left = left.Expression() - } if !ast.IsIdentifier(left) || left.Text() != "Symbol" { return false } @@ -12501,7 +12502,7 @@ func (c *Checker) checkAssertion(node *ast.Node, checkMode CheckMode) *Type { // safe even for `x as const` and keeps diagnostics stable regardless of traversal order. c.checkSourceElement(typeNode) if isConstTypeReference(typeNode) { - if !c.isValidConstAssertionArgument(node.Expression()) { + if !c.isValidConstAssertionArgument(node.Expression()) && exprType.flags&TypeFlagsUniqueESSymbol == 0 { c.error(node.Expression(), diagnostics.A_const_assertion_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals) } return c.getRegularTypeOfLiteralType(exprType) @@ -18584,8 +18585,9 @@ func (c *Checker) widenTypeForVariableLikeDeclaration(t *Type, declaration *ast. c.reportErrorsFromWidening(declaration, t, WideningKindNormal) } - // always widen a 'unique symbol' type if the type was created for a different declaration. - if t.flags&TypeFlagsUniqueESSymbol != 0 && (ast.IsBindingElement(declaration) || declaration.Type() == nil) && t.symbol != c.getSymbolOfDeclaration(declaration) { + // Widen a 'unique symbol' type if the type was created for a different declaration, unless the + // declaration or initializer is const-like. + if t.flags&TypeFlagsUniqueESSymbol != 0 && !c.isConstLikeUniqueSymbolDeclaration(declaration) && (ast.IsBindingElement(declaration) || declaration.Type() == nil) && t.symbol != c.getSymbolOfDeclaration(declaration) { t = c.esSymbolType } return c.getWidenedType(t) @@ -18605,6 +18607,12 @@ func (c *Checker) widenTypeForVariableLikeDeclaration(t *Type, declaration *ast. return t } +func (c *Checker) isConstLikeUniqueSymbolDeclaration(declaration *ast.Node) bool { + return c.getCombinedNodeFlagsCached(declaration)&ast.NodeFlagsConstant != 0 || + isDeclarationReadonly(declaration) || + declaration.Initializer() != nil && ast.IsConstAssertion(ast.SkipParentheses(declaration.Initializer())) +} + func (c *Checker) reportImplicitAny(declaration *ast.Node, t *Type, wideningKind WideningKind) { if ast.IsInJSFile(declaration) && !ast.IsCheckJSEnabledForFile(ast.GetSourceFileOfNode(declaration), c.compilerOptions) { // Only report implicit any errors/suggestions in TS and ts-check JS files @@ -22629,6 +22637,9 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias return c.getTemplateLiteralType(t.AsTemplateLiteralType().texts, c.instantiateTypes(t.AsTemplateLiteralType().types, m)) case flags&TypeFlagsStringMapping != 0: return c.getStringMappingType(t.symbol, c.instantiateType(t.AsStringMappingType().target, m)) + case flags&TypeFlagsRegisteredESSymbol != 0: + newAlias := c.instantiateTypeAlias(t.alias, m) + return c.getRegisteredESSymbolType(newAlias.typeArguments[0], newAlias) case flags&TypeFlagsConditional != 0: return c.getConditionalTypeInstantiation(t, c.combineTypeMappers(t.AsConditionalType().mapper, m), false /*forConstraint*/, alias) case flags&TypeFlagsSubstitution != 0: @@ -22654,6 +22665,10 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias return t } +func isRegisteredSymbolAlias(alias *TypeAlias) bool { + return alias != nil && alias.symbol != nil && alias.symbol.Name == "RegisteredSymbol" && len(alias.typeArguments) == 1 +} + // Handles instantiation of the following object types: // AnonymousType (ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType) // TypeReference with node != nil (ObjectFlagsReference) @@ -23358,6 +23373,68 @@ func (c *Checker) getESSymbolLikeTypeForNode(node *ast.Node) *Type { return c.esSymbolType } +func (c *Checker) getRegisteredESSymbolType(keyType *Type, alias *TypeAlias) *Type { + if keyType.flags&TypeFlagsNever != 0 { + return c.neverType + } + if keyType.flags&TypeFlagsUnion != 0 { + members := make([]*Type, 0, len(keyType.Types())) + for _, member := range keyType.Types() { + if member.flags&TypeFlagsStringOrNumberLiteral == 0 { + return c.esSymbolType + } + memberAlias := &TypeAlias{symbol: alias.symbol, typeArguments: []*Type{member}} + members = append(members, c.getRegisteredESSymbolType(member, memberAlias)) + } + return c.getUnionType(members) + } + if keyType.flags&(TypeFlagsStringOrNumberLiteral|TypeFlagsTypeParameter) == 0 { + return c.esSymbolType + } + key := c.getRegisteredESSymbolTypeKey(keyType) + t := c.registeredESSymbolTypes[key] + if t == nil { + if keyType.flags&TypeFlagsTypeParameter != 0 { + data := &RegisteredESSymbolType{target: keyType} + t = c.newType(TypeFlagsRegisteredESSymbol, ObjectFlagsNone, data) + } else { + name := ast.InternalSymbolNamePrefix + "@@" + c.getRegisteredESSymbolNameText(keyType) + symbol := c.newSymbol(ast.SymbolFlagsProperty, name) + t = c.newUniqueESSymbolType(symbol, name) + } + c.registeredESSymbolTypes[key] = t + } + t.alias = alias + return t +} + +func (c *Checker) getRegisteredESSymbolTypeKey(keyType *Type) CacheHashKey { + var b keyBuilder + b.writeString("RegisteredSymbol") + if keyType.flags&TypeFlagsStringLiteral != 0 { + b.writeByte('s') + b.writeString(getStringLiteralValue(keyType)) + } else if keyType.flags&TypeFlagsNumberLiteral != 0 { + b.writeByte('n') + b.writeString(getNumberLiteralValue(keyType).String()) + } else { + b.writeByte('t') + b.writeType(keyType) + } + return b.hash() +} + +func (c *Checker) getRegisteredESSymbolNameText(keyType *Type) string { + switch { + case keyType.flags&TypeFlagsStringLiteral != 0: + return getStringLiteralValue(keyType) + case keyType.flags&TypeFlagsNumberLiteral != 0: + return getNumberLiteralValue(keyType).String() + default: + return c.typeToStringEx(keyType, nil, TypeFormatFlagsNoTruncation|TypeFormatFlagsUseAliasDefinedOutsideCurrentScope, nil) + } +} + func (c *Checker) getTypeFromTypeReference(node *ast.Node) *Type { links := c.typeNodeLinks.Get(node) if links.resolvedType == nil { @@ -24039,6 +24116,11 @@ func (c *Checker) getTypeAliasInstantiation(symbol *ast.Symbol, typeArguments [] switch typeKind { case IntrinsicTypeKindNoInfer: return c.getNoInferType(typeArguments[0]) + case IntrinsicTypeKindRegisteredSymbol: + if alias == nil { + alias = &TypeAlias{symbol: symbol, typeArguments: typeArguments} + } + return c.getRegisteredESSymbolType(typeArguments[0], alias) default: return c.getStringMappingType(symbol, typeArguments[0]) } @@ -26074,7 +26156,7 @@ func (c *Checker) getUnionTypeWorker(types []*Type, unionReduction UnionReductio typeSet = slices.Delete(typeSet, 1, 2) } } - if includes&(TypeFlagsEnum|TypeFlagsLiteral|TypeFlagsUniqueESSymbol|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || + if includes&(TypeFlagsEnum|TypeFlagsLiteral|TypeFlagsUniqueESSymbol|TypeFlagsRegisteredESSymbol|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || includes&TypeFlagsVoid != 0 && includes&TypeFlagsUndefined != 0 { typeSet = c.removeRedundantLiteralTypes(typeSet, includes, unionReduction&UnionReductionSubtype != 0) } @@ -26247,7 +26329,7 @@ func (c *Checker) removeRedundantLiteralTypes(types []*Type, includes TypeFlags, remove := flags&(TypeFlagsStringLiteral|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 && includes&TypeFlagsString != 0 || flags&TypeFlagsNumberLiteral != 0 && includes&TypeFlagsNumber != 0 || flags&TypeFlagsBigIntLiteral != 0 && includes&TypeFlagsBigInt != 0 || - flags&TypeFlagsUniqueESSymbol != 0 && includes&TypeFlagsESSymbol != 0 || + flags&(TypeFlagsUniqueESSymbol|TypeFlagsRegisteredESSymbol) != 0 && includes&TypeFlagsESSymbol != 0 || reduceVoidUndefined && flags&TypeFlagsUndefined != 0 && includes&TypeFlagsVoid != 0 || isFreshLiteralType(t) && containsType(types, t.AsLiteralType().regularType) if remove { @@ -26514,7 +26596,7 @@ func (c *Checker) getIntersectionTypeEx(types []*Type, flags IntersectionFlags, if includes&TypeFlagsString != 0 && includes&(TypeFlagsStringLiteral|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || includes&TypeFlagsNumber != 0 && includes&TypeFlagsNumberLiteral != 0 || includes&TypeFlagsBigInt != 0 && includes&TypeFlagsBigIntLiteral != 0 || - includes&TypeFlagsESSymbol != 0 && includes&TypeFlagsUniqueESSymbol != 0 || + includes&TypeFlagsESSymbol != 0 && includes&(TypeFlagsUniqueESSymbol|TypeFlagsRegisteredESSymbol) != 0 || includes&TypeFlagsVoid != 0 && includes&TypeFlagsUndefined != 0 || includes&TypeFlagsIncludesEmptyObject != 0 && includes&TypeFlagsDefinitelyNonNullable != 0 { if flags&IntersectionFlagsNoSupertypeReduction == 0 { @@ -26703,7 +26785,7 @@ func (c *Checker) removeRedundantSupertypes(types []*Type, includes TypeFlags) [ remove := t.flags&TypeFlagsString != 0 && includes&(TypeFlagsStringLiteral|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || t.flags&TypeFlagsNumber != 0 && includes&TypeFlagsNumberLiteral != 0 || t.flags&TypeFlagsBigInt != 0 && includes&TypeFlagsBigIntLiteral != 0 || - t.flags&TypeFlagsESSymbol != 0 && includes&TypeFlagsUniqueESSymbol != 0 || + t.flags&TypeFlagsESSymbol != 0 && includes&(TypeFlagsUniqueESSymbol|TypeFlagsRegisteredESSymbol) != 0 || t.flags&TypeFlagsVoid != 0 && includes&TypeFlagsUndefined != 0 || c.IsEmptyAnonymousObjectType(t) && includes&TypeFlagsDefinitelyNonNullable != 0 if remove { @@ -27837,7 +27919,7 @@ func (c *Checker) getBaseConstraintOrType(t *Type) *Type { } func (c *Checker) getBaseConstraintOfType(t *Type) *Type { - if t.flags&(TypeFlagsInstantiableNonPrimitive|TypeFlagsUnionOrIntersection|TypeFlagsTemplateLiteral|TypeFlagsStringMapping|TypeFlagsIndex) != 0 || c.isGenericTupleType(t) { + if t.flags&(TypeFlagsInstantiable|TypeFlagsUnionOrIntersection) != 0 || c.isGenericTupleType(t) { constraint := c.getResolvedBaseConstraint(t, nil) if constraint != c.noConstraintType && constraint != c.circularConstraintType { return constraint @@ -27950,6 +28032,12 @@ func (c *Checker) computeBaseConstraint(t *Type, stack []RecursionId) *Type { return c.getStringMappingType(t.symbol, constraint) } return c.stringType + case t.flags&TypeFlagsRegisteredESSymbol != 0: + constraint := c.getNextBaseConstraint(t.Target(), stack) + if constraint != nil && constraint != t.Target() { + return c.getRegisteredESSymbolType(constraint, t.alias) + } + return c.esSymbolType case t.flags&TypeFlagsIndexedAccess != 0: if c.isMappedTypeGenericIndexedAccess(t) { // For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic, diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 5cd58f6ec95f0..f884a08b09ced 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -2352,6 +2352,14 @@ func (b *NodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati remove() } } + if result == nil { + if declaration != nil && ast.IsVariableDeclaration(declaration) && t.flags&TypeFlagsUniqueESSymbol != 0 && !b.ch.IsValueSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration) { + initializer := declaration.Initializer() + if initializer != nil && ast.IsEntityNameExpression(initializer) { + result = b.f.NewTypeQueryNode(b.f.DeepCloneNode(initializer), nil) + } + } + } if result == nil { if reportedInferenceFallback { oldSuppress := b.ctx.suppressReportInferenceFallback @@ -2568,6 +2576,11 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbolFromNameType(symbol *ast.S return b.createPropertyNameNodeForIdentifierOrLiteral(name, singleQuote, stringNamed, isMethod, symbol) } if nameType.flags&TypeFlagsUniqueESSymbol != 0 { + if isRegisteredSymbolAlias(nameType.alias) && symbol.ValueDeclaration != nil { + if declName := symbol.ValueDeclaration.Name(); declName != nil && ast.IsComputedPropertyName(declName) { + return b.f.DeepCloneNode(declName) + } + } // The reference was tracked in the destination scope by trackComputedName. // Reconstructing its spelling in the source scope must not paint that scope's declarations visible. return b.f.NewComputedPropertyName(b.symbolToExpressionWorker(nameType.AsUniqueESSymbolType().symbol, ast.SymbolFlagsValue)) @@ -2831,12 +2844,52 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode { restoreFlags := b.saveRestoreFlags() b.ctx.flags |= nodebuilder.FlagsInObjectTypeLiteral + var mappedProperties []*ast.Symbol + var ordinaryProperties []*ast.Symbol + for _, property := range resolved.properties { + var nameType *Type + if b.ch.valueSymbolLinks.Has(property) { + nameType = b.ch.valueSymbolLinks.TryGet(property).nameType + } + name := ast.GetNameOfDeclaration(property.ValueDeclaration) + if nameType != nil && nameType.flags&TypeFlagsUniqueESSymbol != 0 && isRegisteredSymbolAlias(nameType.alias) && + name != nil && ast.IsComputedPropertyName(name) && !ast.IsEntityNameExpression(name.Expression()) { + mappedProperties = append(mappedProperties, property) + } else { + ordinaryProperties = append(ordinaryProperties, property) + } + } + if len(mappedProperties) != 0 { + copy := *resolved + copy.properties = ordinaryProperties + resolved = © + } members := b.createTypeNodesFromResolvedType(resolved) + var typeNodes []*ast.TypeNode + if members != nil && len(members.Nodes) != 0 || len(mappedProperties) == 0 { + typeLiteralNode := b.f.NewTypeLiteralNode(members) + b.ctx.approximateLength += 2 + b.e.SetEmitFlags(typeLiteralNode, core.IfElse((b.ctx.flags&nodebuilder.FlagsMultilineObjectLiterals != 0), 0, printer.EFSingleLine)) + typeNodes = append(typeNodes, typeLiteralNode) + } + for _, property := range mappedProperties { + nameType := b.ch.valueSymbolLinks.Get(property).nameType + key := b.f.NewTypeParameterDeclaration(nil, b.f.NewIdentifier("K"), b.typeToTypeNode(nameType), nil, nil) + var readonlyToken *ast.Node + if b.ch.isReadonlySymbol(property) { + readonlyToken = b.f.NewToken(ast.KindReadonlyKeyword) + } + var questionToken *ast.Node + if property.Flags&ast.SymbolFlagsOptional != 0 { + questionToken = b.f.NewToken(ast.KindQuestionToken) + } + typeNodes = append(typeNodes, b.f.NewMappedTypeNode(readonlyToken, key, nil, questionToken, b.typeToTypeNode(b.ch.getNonMissingTypeOfSymbol(property)), nil)) + } restoreFlags() - typeLiteralNode := b.f.NewTypeLiteralNode(members) - b.ctx.approximateLength += 2 - b.e.SetEmitFlags(typeLiteralNode, core.IfElse((b.ctx.flags&nodebuilder.FlagsMultilineObjectLiterals != 0), 0, printer.EFSingleLine)) - return typeLiteralNode + if len(typeNodes) == 1 { + return typeNodes[0] + } + return b.f.NewIntersectionTypeNode(b.f.NewNodeList(typeNodes)) } func getTypeAliasForTypeLiteral(c *Checker, t *Type) *ast.Symbol { @@ -3409,6 +3462,9 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode { } } if t.flags&TypeFlagsUniqueESSymbol != 0 { + if isRegisteredSymbolAlias(t.alias) { + return t.alias.ToTypeReferenceNode(b) + } if b.ctx.flags&nodebuilder.FlagsAllowUniqueESSymbolType == 0 { if b.ch.IsValueSymbolAccessible(t.symbol, b.ctx.enclosingDeclaration) { b.ctx.approximateLength += 6 diff --git a/tsc/internal/checker/relater.go b/tsc/internal/checker/relater.go index 9d71d2504ca0c..b6554b1e0a1e7 100644 --- a/tsc/internal/checker/relater.go +++ b/tsc/internal/checker/relater.go @@ -3397,6 +3397,8 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo if source.AsStringMappingType().Symbol() == target.AsStringMappingType().Symbol() { return r.isRelatedTo(source.AsStringMappingType().target, target.AsStringMappingType().target, RecursionFlagsBoth, false /*reportErrors*/) } + case source.flags&TypeFlagsRegisteredESSymbol != 0: + return r.isRelatedTo(source.AsRegisteredESSymbolType().target, target.AsRegisteredESSymbolType().target, RecursionFlagsBoth, false /*reportErrors*/) } if source.flags&TypeFlagsObject == 0 { return TernaryFalse @@ -3829,6 +3831,21 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo } } } + case source.flags&TypeFlagsRegisteredESSymbol != 0: + if target.flags&TypeFlagsRegisteredESSymbol != 0 { + result = r.isRelatedTo(source.Target(), target.Target(), RecursionFlagsBoth, reportErrors) + if result != TernaryFalse { + return result + } + } else { + constraint := r.c.getBaseConstraintOfType(source) + if constraint != nil { + result = r.isRelatedTo(constraint, target, RecursionFlagsSource, reportErrors) + if result != TernaryFalse { + return result + } + } + } default: // An empty object type is related to any mapped type that includes a '?' modifier. if r.relation != r.c.subtypeRelation && r.relation != r.c.strictSubtypeRelation && isPartialMappedType(target) && r.c.isEmptyObjectType(source) { diff --git a/tsc/internal/checker/types.go b/tsc/internal/checker/types.go index f5a8a37954c85..7d1f56f320b9d 100644 --- a/tsc/internal/checker/types.go +++ b/tsc/internal/checker/types.go @@ -437,39 +437,39 @@ type TypeFlags uint32 // conditional types should sort last as those types are potentially recursive and possibly infinite. const ( - TypeFlagsNone TypeFlags = 0 - TypeFlagsAny TypeFlags = 1 << 0 - TypeFlagsUnknown TypeFlags = 1 << 1 - TypeFlagsUndefined TypeFlags = 1 << 2 - TypeFlagsNull TypeFlags = 1 << 3 - TypeFlagsVoid TypeFlags = 1 << 4 - TypeFlagsString TypeFlags = 1 << 5 - TypeFlagsNumber TypeFlags = 1 << 6 - TypeFlagsBigInt TypeFlags = 1 << 7 - TypeFlagsBoolean TypeFlags = 1 << 8 - TypeFlagsESSymbol TypeFlags = 1 << 9 // Type of symbol primitive introduced in ES6 - TypeFlagsStringLiteral TypeFlags = 1 << 10 - TypeFlagsNumberLiteral TypeFlags = 1 << 11 - TypeFlagsBigIntLiteral TypeFlags = 1 << 12 - TypeFlagsBooleanLiteral TypeFlags = 1 << 13 - TypeFlagsUniqueESSymbol TypeFlags = 1 << 14 // unique symbol - TypeFlagsEnumLiteral TypeFlags = 1 << 15 // Always combined with StringLiteral, NumberLiteral, or Union - TypeFlagsEnum TypeFlags = 1 << 16 // Numeric computed enum member value (must be right after EnumLiteral, see getSortOrderFlags) - TypeFlagsNonPrimitive TypeFlags = 1 << 17 // intrinsic object type - TypeFlagsNever TypeFlags = 1 << 18 // Never type - TypeFlagsTypeParameter TypeFlags = 1 << 19 // Type parameter - TypeFlagsObject TypeFlags = 1 << 20 // Object type - TypeFlagsIndex TypeFlags = 1 << 21 // keyof T - TypeFlagsTemplateLiteral TypeFlags = 1 << 22 // Template literal type - TypeFlagsStringMapping TypeFlags = 1 << 23 // Uppercase/Lowercase type - TypeFlagsSubstitution TypeFlags = 1 << 24 // Type parameter substitution - TypeFlagsIndexedAccess TypeFlags = 1 << 25 // T[K] - TypeFlagsConditional TypeFlags = 1 << 26 // T extends U ? X : Y - TypeFlagsUnion TypeFlags = 1 << 27 // Union (T | U) - TypeFlagsIntersection TypeFlags = 1 << 28 // Intersection (T & U) - TypeFlagsReserved1 TypeFlags = 1 << 29 // Used by union/intersection type construction - TypeFlagsReserved2 TypeFlags = 1 << 30 // Used by union/intersection type construction - TypeFlagsReserved3 TypeFlags = 1 << 31 + TypeFlagsNone TypeFlags = 0 + TypeFlagsAny TypeFlags = 1 << 0 + TypeFlagsUnknown TypeFlags = 1 << 1 + TypeFlagsUndefined TypeFlags = 1 << 2 + TypeFlagsNull TypeFlags = 1 << 3 + TypeFlagsVoid TypeFlags = 1 << 4 + TypeFlagsString TypeFlags = 1 << 5 + TypeFlagsNumber TypeFlags = 1 << 6 + TypeFlagsBigInt TypeFlags = 1 << 7 + TypeFlagsBoolean TypeFlags = 1 << 8 + TypeFlagsESSymbol TypeFlags = 1 << 9 // Type of symbol primitive introduced in ES6 + TypeFlagsStringLiteral TypeFlags = 1 << 10 + TypeFlagsNumberLiteral TypeFlags = 1 << 11 + TypeFlagsBigIntLiteral TypeFlags = 1 << 12 + TypeFlagsBooleanLiteral TypeFlags = 1 << 13 + TypeFlagsUniqueESSymbol TypeFlags = 1 << 14 // unique symbol + TypeFlagsEnumLiteral TypeFlags = 1 << 15 // Always combined with StringLiteral, NumberLiteral, or Union + TypeFlagsEnum TypeFlags = 1 << 16 // Numeric computed enum member value (must be right after EnumLiteral, see getSortOrderFlags) + TypeFlagsNonPrimitive TypeFlags = 1 << 17 // intrinsic object type + TypeFlagsNever TypeFlags = 1 << 18 // Never type + TypeFlagsTypeParameter TypeFlags = 1 << 19 // Type parameter + TypeFlagsObject TypeFlags = 1 << 20 // Object type + TypeFlagsIndex TypeFlags = 1 << 21 // keyof T + TypeFlagsTemplateLiteral TypeFlags = 1 << 22 // Template literal type + TypeFlagsStringMapping TypeFlags = 1 << 23 // Uppercase/Lowercase type + TypeFlagsSubstitution TypeFlags = 1 << 24 // Type parameter substitution + TypeFlagsIndexedAccess TypeFlags = 1 << 25 // T[K] + TypeFlagsConditional TypeFlags = 1 << 26 // T extends U ? X : Y + TypeFlagsUnion TypeFlags = 1 << 27 // Union (T | U) + TypeFlagsIntersection TypeFlags = 1 << 28 // Intersection (T & U) + TypeFlagsReserved1 TypeFlags = 1 << 29 // Used by union/intersection type construction + TypeFlagsReserved2 TypeFlags = 1 << 30 // Used by union/intersection type construction + TypeFlagsRegisteredESSymbol TypeFlags = 1 << 31 // RegisteredSymbol with an unresolved key TypeFlagsAnyOrUnknown = TypeFlagsAny | TypeFlagsUnknown TypeFlagsNullable = TypeFlagsUndefined | TypeFlagsNull @@ -486,7 +486,7 @@ const ( TypeFlagsBigIntLike = TypeFlagsBigInt | TypeFlagsBigIntLiteral TypeFlagsBooleanLike = TypeFlagsBoolean | TypeFlagsBooleanLiteral TypeFlagsEnumLike = TypeFlagsEnum | TypeFlagsEnumLiteral - TypeFlagsESSymbolLike = TypeFlagsESSymbol | TypeFlagsUniqueESSymbol + TypeFlagsESSymbolLike = TypeFlagsESSymbol | TypeFlagsUniqueESSymbol | TypeFlagsRegisteredESSymbol TypeFlagsVoidLike = TypeFlagsVoid | TypeFlagsUndefined TypeFlagsPrimitive = TypeFlagsStringLike | TypeFlagsNumberLike | TypeFlagsBigIntLike | TypeFlagsBooleanLike | TypeFlagsEnumLike | TypeFlagsESSymbolLike | TypeFlagsVoidLike | TypeFlagsNull TypeFlagsDefinitelyNonNullable = TypeFlagsStringLike | TypeFlagsNumberLike | TypeFlagsBigIntLike | TypeFlagsBooleanLike | TypeFlagsEnumLike | TypeFlagsESSymbolLike | TypeFlagsObject | TypeFlagsNonPrimitive @@ -495,7 +495,7 @@ const ( TypeFlagsStructuredType = TypeFlagsObject | TypeFlagsUnion | TypeFlagsIntersection TypeFlagsTypeVariable = TypeFlagsTypeParameter | TypeFlagsIndexedAccess TypeFlagsInstantiableNonPrimitive = TypeFlagsTypeVariable | TypeFlagsConditional | TypeFlagsSubstitution - TypeFlagsInstantiablePrimitive = TypeFlagsIndex | TypeFlagsTemplateLiteral | TypeFlagsStringMapping + TypeFlagsInstantiablePrimitive = TypeFlagsIndex | TypeFlagsTemplateLiteral | TypeFlagsStringMapping | TypeFlagsRegisteredESSymbol TypeFlagsInstantiable = TypeFlagsInstantiableNonPrimitive | TypeFlagsInstantiablePrimitive TypeFlagsStructuredOrInstantiable = TypeFlagsStructuredType | TypeFlagsInstantiable TypeFlagsObjectFlagsType = TypeFlagsAny | TypeFlagsNullable | TypeFlagsNever | TypeFlagsObject | TypeFlagsUnion | TypeFlagsIntersection @@ -503,7 +503,7 @@ const ( TypeFlagsSingleton = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsString | TypeFlagsNumber | TypeFlagsBoolean | TypeFlagsBigInt | TypeFlagsESSymbol | TypeFlagsVoid | TypeFlagsUndefined | TypeFlagsNull | TypeFlagsNever | TypeFlagsNonPrimitive // 'TypeFlagsNarrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never - TypeFlagsNarrowable = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsStructuredOrInstantiable | TypeFlagsStringLike | TypeFlagsNumberLike | TypeFlagsBigIntLike | TypeFlagsBooleanLike | TypeFlagsESSymbol | TypeFlagsUniqueESSymbol | TypeFlagsNonPrimitive + TypeFlagsNarrowable = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsStructuredOrInstantiable | TypeFlagsStringLike | TypeFlagsNumberLike | TypeFlagsBigIntLike | TypeFlagsBooleanLike | TypeFlagsESSymbolLike | TypeFlagsNonPrimitive // The following flags are aggregated during union and intersection type construction TypeFlagsIncludesMask = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsPrimitive | TypeFlagsNever | TypeFlagsObject | TypeFlagsUnion | TypeFlagsIntersection | TypeFlagsNonPrimitive | TypeFlagsTemplateLiteral | TypeFlagsStringMapping // The following flags are used for different purposes during union and intersection type construction @@ -545,6 +545,7 @@ var typeFlagNames = [...]struct { {TypeFlagsIndex, "Index"}, {TypeFlagsTemplateLiteral, "TemplateLiteral"}, {TypeFlagsStringMapping, "StringMapping"}, + {TypeFlagsRegisteredESSymbol, "RegisteredESSymbol"}, {TypeFlagsSubstitution, "Substitution"}, {TypeFlagsIndexedAccess, "IndexedAccess"}, {TypeFlagsConditional, "Conditional"}, @@ -724,8 +725,11 @@ func (t *Type) AsIndexType() *IndexType { return t.data.(*In func (t *Type) AsIndexedAccessType() *IndexedAccessType { return t.data.(*IndexedAccessType) } func (t *Type) AsTemplateLiteralType() *TemplateLiteralType { return t.data.(*TemplateLiteralType) } func (t *Type) AsStringMappingType() *StringMappingType { return t.data.(*StringMappingType) } -func (t *Type) AsSubstitutionType() *SubstitutionType { return t.data.(*SubstitutionType) } -func (t *Type) AsConditionalType() *ConditionalType { return t.data.(*ConditionalType) } +func (t *Type) AsRegisteredESSymbolType() *RegisteredESSymbolType { + return t.data.(*RegisteredESSymbolType) +} +func (t *Type) AsSubstitutionType() *SubstitutionType { return t.data.(*SubstitutionType) } +func (t *Type) AsConditionalType() *ConditionalType { return t.data.(*ConditionalType) } // Casts for embedded struct types @@ -760,6 +764,8 @@ func (t *Type) Target() *Type { return t.AsIndexType().target case t.flags&TypeFlagsStringMapping != 0: return t.AsStringMappingType().target + case t.flags&TypeFlagsRegisteredESSymbol != 0: + return t.AsRegisteredESSymbolType().target case t.flags&TypeFlagsObject != 0 && t.objectFlags&ObjectFlagsMapped != 0: return t.AsMappedType().target } @@ -1247,6 +1253,11 @@ type StringMappingType struct { func (t *StringMappingType) Target() *Type { return t.target } +type RegisteredESSymbolType struct { + ConstrainedType + target *Type +} + type SubstitutionType struct { ConstrainedType baseType *Type // Target type diff --git a/tsc/internal/checker/utilities.go b/tsc/internal/checker/utilities.go index 0a68372fcef3c..acd04cd7bf54b 100644 --- a/tsc/internal/checker/utilities.go +++ b/tsc/internal/checker/utilities.go @@ -616,6 +616,10 @@ func CompareTypes(t1, t2 *Type) int { if c := CompareTypes(t1.AsStringMappingType().target, t2.AsStringMappingType().target); c != 0 { return c } + case t1.flags&TypeFlagsRegisteredESSymbol != 0: + if c := CompareTypes(t1.AsRegisteredESSymbolType().target, t2.AsRegisteredESSymbolType().target); c != 0 { + return c + } } // Fall back to type IDs. This results in type creation order for built-in types. return int(t1.id) - int(t2.id) diff --git a/tsc/testdata/baselines/reference/compiler/doYouNeedToChangeYourTargetLibraryES2015.types b/tsc/testdata/baselines/reference/compiler/doYouNeedToChangeYourTargetLibraryES2015.types index d383a738b8790..db2e89fc734a8 100644 --- a/tsc/testdata/baselines/reference/compiler/doYouNeedToChangeYourTargetLibraryES2015.types +++ b/tsc/testdata/baselines/reference/compiler/doYouNeedToChangeYourTargetLibraryES2015.types @@ -472,11 +472,11 @@ const testPromiseReject = Promise.reject(); >reject : (reason?: any) => Promise const testSymbolFor = Symbol.for('a'); ->testSymbolFor : unique symbol ->Symbol.for('a') : unique symbol ->Symbol.for : (key: string) => symbol +>testSymbolFor : RegisteredSymbol<"a"> +>Symbol.for('a') : RegisteredSymbol<"a"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >'a' : "a" const testSymbolKeyFor = Symbol.keyFor(testSymbolFor); @@ -485,7 +485,7 @@ const testSymbolKeyFor = Symbol.keyFor(testSymbolFor); >Symbol.keyFor : (sym: symbol) => string | undefined >Symbol : SymbolConstructor >keyFor : (sym: symbol) => string | undefined ->testSymbolFor : unique symbol +>testSymbolFor : RegisteredSymbol<"a"> const testWeakMap: WeakMap = null as any; >testWeakMap : WeakMap diff --git a/tsc/testdata/baselines/reference/compiler/objectLiteralPropertyImplicitlyAny.types b/tsc/testdata/baselines/reference/compiler/objectLiteralPropertyImplicitlyAny.types index 4e3af7fa9fafa..1660594cd2f93 100644 --- a/tsc/testdata/baselines/reference/compiler/objectLiteralPropertyImplicitlyAny.types +++ b/tsc/testdata/baselines/reference/compiler/objectLiteralPropertyImplicitlyAny.types @@ -2,17 +2,17 @@ === objectLiteralPropertyImplicitlyAny.ts === const foo = Symbol.for("foo"); ->foo : unique symbol ->Symbol.for("foo") : unique symbol ->Symbol.for : (key: string) => symbol +>foo : RegisteredSymbol<"foo"> +>Symbol.for("foo") : RegisteredSymbol<"foo"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"foo" : "foo" const o = { [foo]: undefined }; >o : { [foo]: undefined; } >{ [foo]: undefined } : { [foo]: undefined; } >[foo] : undefined ->foo : unique symbol +>foo : RegisteredSymbol<"foo"> >undefined : undefined diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.js b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.js new file mode 100644 index 0000000000000..bc1d488b54574 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.js @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts] //// + +//// [registeredSymbolComputedNameDeclaration.ts] +export const key = Symbol.for("abc"); +export function getKey(): typeof key { return key; } + +export const value = { + ordinary: 1, + [getKey()]: "text", + [Symbol.for("other")]: true, +}; + +export const readonlyValue = { [getKey()]: "fixed" } as const; + + +//// [registeredSymbolComputedNameDeclaration.js] +export const key = Symbol.for("abc"); +export function getKey() { return key; } +export const value = { + ordinary: 1, + [getKey()]: "text", + [Symbol.for("other")]: true, +}; +export const readonlyValue = { [getKey()]: "fixed" }; + + +//// [registeredSymbolComputedNameDeclaration.d.ts] +export declare const key: RegisteredSymbol<"abc">; +export declare function getKey(): typeof key; +export declare const value: { + ordinary: number; +} & { + [K in RegisteredSymbol<"abc">]: string; +} & { + [K in RegisteredSymbol<"other">]: boolean; +}; +export declare const readonlyValue: { + readonly [K in RegisteredSymbol<"abc">]: "fixed"; +}; diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.symbols b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.symbols new file mode 100644 index 0000000000000..a78d3938910ab --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.symbols @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts] //// + +=== registeredSymbolComputedNameDeclaration.ts === +export const key = Symbol.for("abc"); +>key : Symbol(key, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 12)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +export function getKey(): typeof key { return key; } +>getKey : Symbol(getKey, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 37)) +>key : Symbol(key, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 12)) +>key : Symbol(key, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 12)) + +export const value = { +>value : Symbol(value, Decl(registeredSymbolComputedNameDeclaration.ts, 3, 12)) + + ordinary: 1, +>ordinary : Symbol(ordinary, Decl(registeredSymbolComputedNameDeclaration.ts, 3, 22)) + + [getKey()]: "text", +>[getKey()] : Symbol([getKey()], Decl(registeredSymbolComputedNameDeclaration.ts, 4, 16)) +>getKey : Symbol(getKey, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 37)) + + [Symbol.for("other")]: true, +>[Symbol.for("other")] : Symbol([Symbol.for("other")], Decl(registeredSymbolComputedNameDeclaration.ts, 5, 23)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +}; + +export const readonlyValue = { [getKey()]: "fixed" } as const; +>readonlyValue : Symbol(readonlyValue, Decl(registeredSymbolComputedNameDeclaration.ts, 9, 12)) +>[getKey()] : Symbol([getKey()], Decl(registeredSymbolComputedNameDeclaration.ts, 9, 30)) +>getKey : Symbol(getKey, Decl(registeredSymbolComputedNameDeclaration.ts, 0, 37)) +>const : Symbol(const) + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.types b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.types new file mode 100644 index 0000000000000..a3de8a2fe5995 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolComputedNameDeclaration.types @@ -0,0 +1,50 @@ +//// [tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts] //// + +=== registeredSymbolComputedNameDeclaration.ts === +export const key = Symbol.for("abc"); +>key : RegisteredSymbol<"abc"> +>Symbol.for("abc") : RegisteredSymbol<"abc"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"abc" : "abc" + +export function getKey(): typeof key { return key; } +>getKey : () => typeof key +>key : RegisteredSymbol<"abc"> +>key : RegisteredSymbol<"abc"> + +export const value = { +>value : { ordinary: number; } & { [K in RegisteredSymbol<"abc">]: string;} & { [K in RegisteredSymbol<"other">]: boolean;} +>{ ordinary: 1, [getKey()]: "text", [Symbol.for("other")]: true,} : { ordinary: number; } & { [K in RegisteredSymbol<"abc">]: string;} & { [K in RegisteredSymbol<"other">]: boolean;} + + ordinary: 1, +>ordinary : number +>1 : 1 + + [getKey()]: "text", +>[getKey()] : string +>getKey() : RegisteredSymbol<"abc"> +>getKey : () => typeof key +>"text" : "text" + + [Symbol.for("other")]: true, +>[Symbol.for("other")] : boolean +>Symbol.for("other") : RegisteredSymbol<"other"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"other" : "other" +>true : true + +}; + +export const readonlyValue = { [getKey()]: "fixed" } as const; +>readonlyValue : { readonly [K in RegisteredSymbol<"abc">]: "fixed";} +>{ [getKey()]: "fixed" } as const : { readonly [K in RegisteredSymbol<"abc">]: "fixed";} +>{ [getKey()]: "fixed" } : { readonly [K in RegisteredSymbol<"abc">]: "fixed";} +>[getKey()] : "fixed" +>getKey() : RegisteredSymbol<"abc"> +>getKey : () => typeof key +>"fixed" : "fixed" + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.errors.txt b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.errors.txt new file mode 100644 index 0000000000000..69deb62582dc4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.errors.txt @@ -0,0 +1,28 @@ +registeredSymbolDeferredKey.ts(15,11): error TS2322: Type '"first" | undefined' is not assignable to type '"first"'. + Type 'undefined' is not assignable to type '"first"'. + + +==== registeredSymbolDeferredKey.ts (1 errors) ==== + export function make(key: K) { + const registered = Symbol.for(key); + const widened: symbol = registered; + return registered; + } + + export function unreachable(key: never): never { + return Symbol.for(key); + } + + export function read(first: K, second: K) { + const firstKey = Symbol.for(first); + const record = { [firstKey]: "first" } as const; + const secondKey = Symbol.for(second); + const value: "first" = record[secondKey]; + ~~~~~ +!!! error TS2322: Type '"first" | undefined' is not assignable to type '"first"'. +!!! error TS2322: Type 'undefined' is not assignable to type '"first"'. + return value; + } + + read<"a" | "b">("a", "b"); + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.js b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.js new file mode 100644 index 0000000000000..9f7cb0438d3a8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/registeredSymbolDeferredKey.ts] //// + +//// [registeredSymbolDeferredKey.ts] +export function make(key: K) { + const registered = Symbol.for(key); + const widened: symbol = registered; + return registered; +} + +export function unreachable(key: never): never { + return Symbol.for(key); +} + +export function read(first: K, second: K) { + const firstKey = Symbol.for(first); + const record = { [firstKey]: "first" } as const; + const secondKey = Symbol.for(second); + const value: "first" = record[secondKey]; + return value; +} + +read<"a" | "b">("a", "b"); + + + + +//// [registeredSymbolDeferredKey.d.ts] +export declare function make(key: K): RegisteredSymbol; +export declare function unreachable(key: never): never; +export declare function read(first: K, second: K): "first"; diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.symbols b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.symbols new file mode 100644 index 0000000000000..064eb83aba8e3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.symbols @@ -0,0 +1,75 @@ +//// [tests/cases/compiler/registeredSymbolDeferredKey.ts] //// + +=== registeredSymbolDeferredKey.ts === +export function make(key: K) { +>make : Symbol(make, Decl(registeredSymbolDeferredKey.ts, 0, 0)) +>K : Symbol(K, Decl(registeredSymbolDeferredKey.ts, 0, 21)) +>key : Symbol(key, Decl(registeredSymbolDeferredKey.ts, 0, 39)) +>K : Symbol(K, Decl(registeredSymbolDeferredKey.ts, 0, 21)) + + const registered = Symbol.for(key); +>registered : Symbol(registered, Decl(registeredSymbolDeferredKey.ts, 1, 9)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>key : Symbol(key, Decl(registeredSymbolDeferredKey.ts, 0, 39)) + + const widened: symbol = registered; +>widened : Symbol(widened, Decl(registeredSymbolDeferredKey.ts, 2, 9)) +>registered : Symbol(registered, Decl(registeredSymbolDeferredKey.ts, 1, 9)) + + return registered; +>registered : Symbol(registered, Decl(registeredSymbolDeferredKey.ts, 1, 9)) +} + +export function unreachable(key: never): never { +>unreachable : Symbol(unreachable, Decl(registeredSymbolDeferredKey.ts, 4, 1)) +>key : Symbol(key, Decl(registeredSymbolDeferredKey.ts, 6, 28)) + + return Symbol.for(key); +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>key : Symbol(key, Decl(registeredSymbolDeferredKey.ts, 6, 28)) +} + +export function read(first: K, second: K) { +>read : Symbol(read, Decl(registeredSymbolDeferredKey.ts, 8, 1)) +>K : Symbol(K, Decl(registeredSymbolDeferredKey.ts, 10, 21)) +>first : Symbol(first, Decl(registeredSymbolDeferredKey.ts, 10, 39)) +>K : Symbol(K, Decl(registeredSymbolDeferredKey.ts, 10, 21)) +>second : Symbol(second, Decl(registeredSymbolDeferredKey.ts, 10, 48)) +>K : Symbol(K, Decl(registeredSymbolDeferredKey.ts, 10, 21)) + + const firstKey = Symbol.for(first); +>firstKey : Symbol(firstKey, Decl(registeredSymbolDeferredKey.ts, 11, 9)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>first : Symbol(first, Decl(registeredSymbolDeferredKey.ts, 10, 39)) + + const record = { [firstKey]: "first" } as const; +>record : Symbol(record, Decl(registeredSymbolDeferredKey.ts, 12, 9)) +>[firstKey] : Symbol([firstKey], Decl(registeredSymbolDeferredKey.ts, 12, 20)) +>firstKey : Symbol(firstKey, Decl(registeredSymbolDeferredKey.ts, 11, 9)) +>const : Symbol(const) + + const secondKey = Symbol.for(second); +>secondKey : Symbol(secondKey, Decl(registeredSymbolDeferredKey.ts, 13, 9)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>second : Symbol(second, Decl(registeredSymbolDeferredKey.ts, 10, 48)) + + const value: "first" = record[secondKey]; +>value : Symbol(value, Decl(registeredSymbolDeferredKey.ts, 14, 9)) +>record : Symbol(record, Decl(registeredSymbolDeferredKey.ts, 12, 9)) +>secondKey : Symbol(secondKey, Decl(registeredSymbolDeferredKey.ts, 13, 9)) + + return value; +>value : Symbol(value, Decl(registeredSymbolDeferredKey.ts, 14, 9)) +} + +read<"a" | "b">("a", "b"); +>read : Symbol(read, Decl(registeredSymbolDeferredKey.ts, 8, 1)) + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.types b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.types new file mode 100644 index 0000000000000..f0641e90cbe8a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolDeferredKey.types @@ -0,0 +1,80 @@ +//// [tests/cases/compiler/registeredSymbolDeferredKey.ts] //// + +=== registeredSymbolDeferredKey.ts === +export function make(key: K) { +>make : (key: K) => RegisteredSymbol +>key : K + + const registered = Symbol.for(key); +>registered : RegisteredSymbol +>Symbol.for(key) : RegisteredSymbol +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>key : K + + const widened: symbol = registered; +>widened : symbol +>registered : RegisteredSymbol + + return registered; +>registered : RegisteredSymbol +} + +export function unreachable(key: never): never { +>unreachable : (key: never) => never +>key : never + + return Symbol.for(key); +>Symbol.for(key) : never +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>key : never +} + +export function read(first: K, second: K) { +>read : (first: K, second: K) => "first" +>first : K +>second : K + + const firstKey = Symbol.for(first); +>firstKey : RegisteredSymbol +>Symbol.for(first) : RegisteredSymbol +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>first : K + + const record = { [firstKey]: "first" } as const; +>record : { readonly [x: symbol]: "first"; } +>{ [firstKey]: "first" } as const : { readonly [x: symbol]: "first"; } +>{ [firstKey]: "first" } : { readonly [x: symbol]: "first"; } +>[firstKey] : "first" +>firstKey : RegisteredSymbol +>"first" : "first" + + const secondKey = Symbol.for(second); +>secondKey : RegisteredSymbol +>Symbol.for(second) : RegisteredSymbol +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>second : K + + const value: "first" = record[secondKey]; +>value : "first" +>record[secondKey] : "first" | undefined +>record : { readonly [x: symbol]: "first"; } +>secondKey : RegisteredSymbol + + return value; +>value : "first" +} + +read<"a" | "b">("a", "b"); +>read<"a" | "b">("a", "b") : "first" +>read : (first: K, second: K) => "first" +>"a" : "a" +>"b" : "b" + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.symbols b/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.symbols new file mode 100644 index 0000000000000..cded039b62e43 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.symbols @@ -0,0 +1,107 @@ +//// [tests/cases/compiler/registeredSymbolGenericRelations.ts] //// + +=== registeredSymbolGenericRelations.ts === +type Equal = +>Equal : Symbol(Equal, Decl(registeredSymbolGenericRelations.ts, 0, 0)) +>A : Symbol(A, Decl(registeredSymbolGenericRelations.ts, 0, 11)) +>B : Symbol(B, Decl(registeredSymbolGenericRelations.ts, 0, 13)) + + (() => T extends A ? 1 : 2) extends +>T : Symbol(T, Decl(registeredSymbolGenericRelations.ts, 1, 6)) +>T : Symbol(T, Decl(registeredSymbolGenericRelations.ts, 1, 6)) +>A : Symbol(A, Decl(registeredSymbolGenericRelations.ts, 0, 11)) + + (() => T extends B ? 1 : 2) ? true : false; +>T : Symbol(T, Decl(registeredSymbolGenericRelations.ts, 2, 6)) +>T : Symbol(T, Decl(registeredSymbolGenericRelations.ts, 2, 6)) +>B : Symbol(B, Decl(registeredSymbolGenericRelations.ts, 0, 13)) + +declare function inferKey(value: RegisteredSymbol): K; +>inferKey : Symbol(inferKey, Decl(registeredSymbolGenericRelations.ts, 2, 50)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 4, 26)) +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 4, 44)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 4, 26)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 4, 26)) + +const inferred: "foo" = inferKey(Symbol.for("foo")); +>inferred : Symbol(inferred, Decl(registeredSymbolGenericRelations.ts, 5, 5)) +>inferKey : Symbol(inferKey, Decl(registeredSymbolGenericRelations.ts, 2, 50)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +function simplify() { +>simplify : Symbol(simplify, Decl(registeredSymbolGenericRelations.ts, 5, 52)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 7, 18)) + + const unionIsSymbol: true = null! as Equal | symbol, symbol>; +>unionIsSymbol : Symbol(unionIsSymbol, Decl(registeredSymbolGenericRelations.ts, 8, 9)) +>Equal : Symbol(Equal, Decl(registeredSymbolGenericRelations.ts, 0, 0)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 7, 18)) + + const intersectionIsRegistered: true = null! as Equal & symbol, RegisteredSymbol>; +>intersectionIsRegistered : Symbol(intersectionIsRegistered, Decl(registeredSymbolGenericRelations.ts, 9, 9)) +>Equal : Symbol(Equal, Decl(registeredSymbolGenericRelations.ts, 0, 0)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 7, 18)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 7, 18)) + + return { unionIsSymbol, intersectionIsRegistered }; +>unionIsSymbol : Symbol(unionIsSymbol, Decl(registeredSymbolGenericRelations.ts, 10, 12)) +>intersectionIsRegistered : Symbol(intersectionIsRegistered, Decl(registeredSymbolGenericRelations.ts, 10, 27)) +} + +function widenKey(value: RegisteredSymbol): RegisteredSymbol<"foo" | "bar"> { +>widenKey : Symbol(widenKey, Decl(registeredSymbolGenericRelations.ts, 11, 1)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 13, 18)) +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 13, 43)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 13, 18)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) + + return value; +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 13, 43)) +} + +function widenGeneric(value: RegisteredSymbol): RegisteredSymbol { +>widenGeneric : Symbol(widenGeneric, Decl(registeredSymbolGenericRelations.ts, 15, 1)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 17, 22)) +>L : Symbol(L, Decl(registeredSymbolGenericRelations.ts, 17, 34)) +>L : Symbol(L, Decl(registeredSymbolGenericRelations.ts, 17, 34)) +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 17, 53)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 17, 22)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>L : Symbol(L, Decl(registeredSymbolGenericRelations.ts, 17, 34)) + + return value; +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 17, 53)) +} + +function commonSymbol(value: RegisteredSymbol): symbol { +>commonSymbol : Symbol(commonSymbol, Decl(registeredSymbolGenericRelations.ts, 19, 1)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 21, 22)) +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 21, 40)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 21, 22)) + + return value; +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 21, 40)) +} + +function intersect(value: RegisteredSymbol): RegisteredSymbol & symbol { +>intersect : Symbol(intersect, Decl(registeredSymbolGenericRelations.ts, 23, 1)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 25, 19)) +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 25, 37)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 25, 19)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>K : Symbol(K, Decl(registeredSymbolGenericRelations.ts, 25, 19)) + + return value; +>value : Symbol(value, Decl(registeredSymbolGenericRelations.ts, 25, 37)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.types b/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.types new file mode 100644 index 0000000000000..c9d46c09a2897 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolGenericRelations.types @@ -0,0 +1,78 @@ +//// [tests/cases/compiler/registeredSymbolGenericRelations.ts] //// + +=== registeredSymbolGenericRelations.ts === +type Equal = +>Equal : Equal + + (() => T extends A ? 1 : 2) extends + (() => T extends B ? 1 : 2) ? true : false; +>true : true +>false : false + +declare function inferKey(value: RegisteredSymbol): K; +>inferKey : (value: RegisteredSymbol) => K +>value : RegisteredSymbol + +const inferred: "foo" = inferKey(Symbol.for("foo")); +>inferred : "foo" +>inferKey(Symbol.for("foo")) : "foo" +>inferKey : (value: RegisteredSymbol) => K +>Symbol.for("foo") : RegisteredSymbol<"foo"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"foo" : "foo" + +function simplify() { +>simplify : () => { unionIsSymbol: true; intersectionIsRegistered: true; } + + const unionIsSymbol: true = null! as Equal | symbol, symbol>; +>unionIsSymbol : true +>true : true +>null! as Equal | symbol, symbol> : true +>null! : never + + const intersectionIsRegistered: true = null! as Equal & symbol, RegisteredSymbol>; +>intersectionIsRegistered : true +>true : true +>null! as Equal & symbol, RegisteredSymbol> : true +>null! : never + + return { unionIsSymbol, intersectionIsRegistered }; +>{ unionIsSymbol, intersectionIsRegistered } : { unionIsSymbol: true; intersectionIsRegistered: true; } +>unionIsSymbol : true +>intersectionIsRegistered : true +} + +function widenKey(value: RegisteredSymbol): RegisteredSymbol<"foo" | "bar"> { +>widenKey : (value: RegisteredSymbol) => RegisteredSymbol<"foo" | "bar"> +>value : RegisteredSymbol + + return value; +>value : RegisteredSymbol<"bar"> | RegisteredSymbol<"foo"> +} + +function widenGeneric(value: RegisteredSymbol): RegisteredSymbol { +>widenGeneric : (value: RegisteredSymbol) => RegisteredSymbol +>value : RegisteredSymbol + + return value; +>value : RegisteredSymbol +} + +function commonSymbol(value: RegisteredSymbol): symbol { +>commonSymbol : (value: RegisteredSymbol) => symbol +>value : RegisteredSymbol + + return value; +>value : RegisteredSymbol +} + +function intersect(value: RegisteredSymbol): RegisteredSymbol & symbol { +>intersect : (value: RegisteredSymbol) => RegisteredSymbol & symbol +>value : RegisteredSymbol + + return value; +>value : RegisteredSymbol +} + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.errors.txt b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.errors.txt new file mode 100644 index 0000000000000..3df1f07aa86e0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.errors.txt @@ -0,0 +1,34 @@ +registeredSymbolIntrinsic.ts(13,5): error TS2322: Type 'symbol' is not assignable to type 'RegisteredSymbol<"foo">'. +registeredSymbolIntrinsic.ts(17,5): error TS2322: Type 'RegisteredSymbol<"bar"> | RegisteredSymbol<"foo">' is not assignable to type 'RegisteredSymbol<"foo">'. + Type 'RegisteredSymbol<"bar">' is not assignable to type 'RegisteredSymbol<"foo">'. + + +==== registeredSymbolIntrinsic.ts (2 errors) ==== + const foo = Symbol.for("foo"); + const fooAgain = Symbol.for("foo"); + const bar = Symbol.for("bar"); + + let sameStringKey: typeof foo = fooAgain; + let registeredStringKey: RegisteredSymbol<"foo"> = foo; + let registeredBarKey: RegisteredSymbol<"bar"> = bar; + let widenedSymbol: symbol = foo; + + declare const key: string; + let registeredString: RegisteredSymbol = Symbol.for(key); + let dynamic = Symbol.for(key); + let invalidDynamicKey: typeof foo = dynamic; + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'symbol' is not assignable to type 'RegisteredSymbol<"foo">'. + + declare const unionKey: "foo" | "bar"; + let registeredUnion: RegisteredSymbol<"foo" | "bar"> = Symbol.for(unionKey); + let invalidUnionKey: typeof foo = registeredUnion; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'RegisteredSymbol<"bar"> | RegisteredSymbol<"foo">' is not assignable to type 'RegisteredSymbol<"foo">'. +!!! error TS2322: Type 'RegisteredSymbol<"bar">' is not assignable to type 'RegisteredSymbol<"foo">'. + + interface WithRegisteredKeys { + [foo]: string; + [bar]: number; + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.symbols b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.symbols new file mode 100644 index 0000000000000..a7feea4365e28 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.symbols @@ -0,0 +1,91 @@ +//// [tests/cases/compiler/registeredSymbolIntrinsic.ts] //// + +=== registeredSymbolIntrinsic.ts === +const foo = Symbol.for("foo"); +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +const fooAgain = Symbol.for("foo"); +>fooAgain : Symbol(fooAgain, Decl(registeredSymbolIntrinsic.ts, 1, 5)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +const bar = Symbol.for("bar"); +>bar : Symbol(bar, Decl(registeredSymbolIntrinsic.ts, 2, 5)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +let sameStringKey: typeof foo = fooAgain; +>sameStringKey : Symbol(sameStringKey, Decl(registeredSymbolIntrinsic.ts, 4, 3)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) +>fooAgain : Symbol(fooAgain, Decl(registeredSymbolIntrinsic.ts, 1, 5)) + +let registeredStringKey: RegisteredSymbol<"foo"> = foo; +>registeredStringKey : Symbol(registeredStringKey, Decl(registeredSymbolIntrinsic.ts, 5, 3)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) + +let registeredBarKey: RegisteredSymbol<"bar"> = bar; +>registeredBarKey : Symbol(registeredBarKey, Decl(registeredSymbolIntrinsic.ts, 6, 3)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>bar : Symbol(bar, Decl(registeredSymbolIntrinsic.ts, 2, 5)) + +let widenedSymbol: symbol = foo; +>widenedSymbol : Symbol(widenedSymbol, Decl(registeredSymbolIntrinsic.ts, 7, 3)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) + +declare const key: string; +>key : Symbol(key, Decl(registeredSymbolIntrinsic.ts, 9, 13)) + +let registeredString: RegisteredSymbol = Symbol.for(key); +>registeredString : Symbol(registeredString, Decl(registeredSymbolIntrinsic.ts, 10, 3)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>key : Symbol(key, Decl(registeredSymbolIntrinsic.ts, 9, 13)) + +let dynamic = Symbol.for(key); +>dynamic : Symbol(dynamic, Decl(registeredSymbolIntrinsic.ts, 11, 3)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>key : Symbol(key, Decl(registeredSymbolIntrinsic.ts, 9, 13)) + +let invalidDynamicKey: typeof foo = dynamic; +>invalidDynamicKey : Symbol(invalidDynamicKey, Decl(registeredSymbolIntrinsic.ts, 12, 3)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) +>dynamic : Symbol(dynamic, Decl(registeredSymbolIntrinsic.ts, 11, 3)) + +declare const unionKey: "foo" | "bar"; +>unionKey : Symbol(unionKey, Decl(registeredSymbolIntrinsic.ts, 14, 13)) + +let registeredUnion: RegisteredSymbol<"foo" | "bar"> = Symbol.for(unionKey); +>registeredUnion : Symbol(registeredUnion, Decl(registeredSymbolIntrinsic.ts, 15, 3)) +>RegisteredSymbol : Symbol(RegisteredSymbol, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>unionKey : Symbol(unionKey, Decl(registeredSymbolIntrinsic.ts, 14, 13)) + +let invalidUnionKey: typeof foo = registeredUnion; +>invalidUnionKey : Symbol(invalidUnionKey, Decl(registeredSymbolIntrinsic.ts, 16, 3)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) +>registeredUnion : Symbol(registeredUnion, Decl(registeredSymbolIntrinsic.ts, 15, 3)) + +interface WithRegisteredKeys { +>WithRegisteredKeys : Symbol(WithRegisteredKeys, Decl(registeredSymbolIntrinsic.ts, 16, 50)) + + [foo]: string; +>[foo] : Symbol(WithRegisteredKeys[foo], Decl(registeredSymbolIntrinsic.ts, 18, 30)) +>foo : Symbol(foo, Decl(registeredSymbolIntrinsic.ts, 0, 5)) + + [bar]: number; +>[bar] : Symbol(WithRegisteredKeys[bar], Decl(registeredSymbolIntrinsic.ts, 19, 18)) +>bar : Symbol(bar, Decl(registeredSymbolIntrinsic.ts, 2, 5)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.types b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.types new file mode 100644 index 0000000000000..bf19d3a392e6c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolIntrinsic.types @@ -0,0 +1,94 @@ +//// [tests/cases/compiler/registeredSymbolIntrinsic.ts] //// + +=== registeredSymbolIntrinsic.ts === +const foo = Symbol.for("foo"); +>foo : RegisteredSymbol<"foo"> +>Symbol.for("foo") : RegisteredSymbol<"foo"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"foo" : "foo" + +const fooAgain = Symbol.for("foo"); +>fooAgain : RegisteredSymbol<"foo"> +>Symbol.for("foo") : RegisteredSymbol<"foo"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"foo" : "foo" + +const bar = Symbol.for("bar"); +>bar : RegisteredSymbol<"bar"> +>Symbol.for("bar") : RegisteredSymbol<"bar"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"bar" : "bar" + +let sameStringKey: typeof foo = fooAgain; +>sameStringKey : RegisteredSymbol<"foo"> +>foo : RegisteredSymbol<"foo"> +>fooAgain : RegisteredSymbol<"foo"> + +let registeredStringKey: RegisteredSymbol<"foo"> = foo; +>registeredStringKey : RegisteredSymbol<"foo"> +>foo : RegisteredSymbol<"foo"> + +let registeredBarKey: RegisteredSymbol<"bar"> = bar; +>registeredBarKey : RegisteredSymbol<"bar"> +>bar : RegisteredSymbol<"bar"> + +let widenedSymbol: symbol = foo; +>widenedSymbol : symbol +>foo : RegisteredSymbol<"foo"> + +declare const key: string; +>key : string + +let registeredString: RegisteredSymbol = Symbol.for(key); +>registeredString : symbol +>Symbol.for(key) : symbol +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>key : string + +let dynamic = Symbol.for(key); +>dynamic : symbol +>Symbol.for(key) : symbol +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>key : string + +let invalidDynamicKey: typeof foo = dynamic; +>invalidDynamicKey : RegisteredSymbol<"foo"> +>foo : RegisteredSymbol<"foo"> +>dynamic : symbol + +declare const unionKey: "foo" | "bar"; +>unionKey : "bar" | "foo" + +let registeredUnion: RegisteredSymbol<"foo" | "bar"> = Symbol.for(unionKey); +>registeredUnion : RegisteredSymbol<"bar"> | RegisteredSymbol<"foo"> +>Symbol.for(unionKey) : RegisteredSymbol<"bar"> | RegisteredSymbol<"foo"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>unionKey : "bar" | "foo" + +let invalidUnionKey: typeof foo = registeredUnion; +>invalidUnionKey : RegisteredSymbol<"foo"> +>foo : RegisteredSymbol<"foo"> +>registeredUnion : RegisteredSymbol<"bar"> | RegisteredSymbol<"foo"> + +interface WithRegisteredKeys { + [foo]: string; +>[foo] : string +>foo : RegisteredSymbol<"foo"> + + [bar]: number; +>[bar] : number +>bar : RegisteredSymbol<"bar"> +} + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.js b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.js new file mode 100644 index 0000000000000..3820c660f7a44 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.js @@ -0,0 +1,95 @@ +//// [tests/cases/compiler/registeredSymbolPropertyAccess.ts] //// + +//// [registeredSymbolPropertyAccess.ts] +export const single = Symbol.for("single"); +export const twin1 = Symbol.for("twin"); +export const twin2 = Symbol.for("twin"); +export const unique1 = Symbol("unique"); +export const unique2 = Symbol("unique"); +export const wellKnown = Symbol.match; +export const wellKnown2 = Symbol.toStringTag; + +export const record1 = { + [single]: "single", + [twin2]: "twin", + [unique1]: "unique1", + [unique2]: "unique2", +} as const; +export let singleVal: string = record1[single] satisfies "single"; +export let twin1Val: string = record1[twin1] satisfies "twin"; +export let twin2Val: string = record1[twin2] satisfies "twin"; +export let unique1Val: string = record1[unique1] satisfies "unique1"; +export let unique2Val: string = record1[unique2] satisfies "unique2"; + +export const record2 = { + ...record1, + [unique1]: "unique1New", + [wellKnown]: "wellKnown", +} as const; +singleVal = record2[single] satisfies "single"; +twin1Val = record2[twin1] satisfies "twin"; +twin2Val = record2[twin2] satisfies "twin"; +unique1Val = record2[unique1] satisfies "unique1New"; +unique2Val = record2[unique2] satisfies "unique2"; +export let wellKnownVal: string = record2[wellKnown] satisfies "wellKnown"; + +export const record3 = { + [single]: "single", + [twin2]: "twin", + [unique1]: "unique1", + [unique2]: "unique2", + [wellKnown]: "wellKnown", +} as const; +singleVal = record3[single] satisfies "single"; +twin1Val = record3[twin1] satisfies "twin"; +twin2Val = record3[twin2] satisfies "twin"; +unique1Val = record3[unique1] satisfies "unique1"; +unique2Val = record3[unique2] satisfies "unique2"; +wellKnownVal = record3[wellKnown] satisfies "wellKnown"; + +export const record4 = { + [wellKnown2]: "wellKnown2", +} as const; +export let wellKnown2Val: string = record4[wellKnown2] satisfies "wellKnown2"; + + + + +//// [registeredSymbolPropertyAccess.d.ts] +export declare const single: RegisteredSymbol<"single">; +export declare const twin1: RegisteredSymbol<"twin">; +export declare const twin2: RegisteredSymbol<"twin">; +export declare const unique1: unique symbol; +export declare const unique2: unique symbol; +export declare const wellKnown: typeof Symbol.match; +export declare const wellKnown2: typeof Symbol.toStringTag; +export declare const record1: { + readonly [single]: "single"; + readonly [twin2]: "twin"; + readonly [unique1]: "unique1"; + readonly [unique2]: "unique2"; +}; +export declare let singleVal: string; +export declare let twin1Val: string; +export declare let twin2Val: string; +export declare let unique1Val: string; +export declare let unique2Val: string; +export declare const record2: { + readonly [single]: "single"; + readonly [twin2]: "twin"; + readonly [unique2]: "unique2"; + readonly [unique1]: "unique1New"; + readonly [Symbol.match]: "wellKnown"; +}; +export declare let wellKnownVal: string; +export declare const record3: { + readonly [single]: "single"; + readonly [twin2]: "twin"; + readonly [unique1]: "unique1"; + readonly [unique2]: "unique2"; + readonly [Symbol.match]: "wellKnown"; +}; +export declare const record4: { + readonly [Symbol.toStringTag]: "wellKnown2"; +}; +export declare let wellKnown2Val: string; diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.symbols b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.symbols new file mode 100644 index 0000000000000..6fdc07d3e00bd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.symbols @@ -0,0 +1,206 @@ +//// [tests/cases/compiler/registeredSymbolPropertyAccess.ts] //// + +=== registeredSymbolPropertyAccess.ts === +export const single = Symbol.for("single"); +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +export const twin1 = Symbol.for("twin"); +>twin1 : Symbol(twin1, Decl(registeredSymbolPropertyAccess.ts, 1, 12)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +export const twin2 = Symbol.for("twin"); +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) + +export const unique1 = Symbol("unique"); +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export const unique2 = Symbol("unique"); +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export const wellKnown = Symbol.match; +>wellKnown : Symbol(wellKnown, Decl(registeredSymbolPropertyAccess.ts, 5, 12)) +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export const wellKnown2 = Symbol.toStringTag; +>wellKnown2 : Symbol(wellKnown2, Decl(registeredSymbolPropertyAccess.ts, 6, 12)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export const record1 = { +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) + + [single]: "single", +>[single] : Symbol([single], Decl(registeredSymbolPropertyAccess.ts, 8, 24)) +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) + + [twin2]: "twin", +>[twin2] : Symbol([twin2], Decl(registeredSymbolPropertyAccess.ts, 9, 23)) +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) + + [unique1]: "unique1", +>[unique1] : Symbol([unique1], Decl(registeredSymbolPropertyAccess.ts, 10, 20)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + + [unique2]: "unique2", +>[unique2] : Symbol([unique2], Decl(registeredSymbolPropertyAccess.ts, 11, 25)) +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) + +} as const; +>const : Symbol(const) + +export let singleVal: string = record1[single] satisfies "single"; +>singleVal : Symbol(singleVal, Decl(registeredSymbolPropertyAccess.ts, 14, 10)) +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) + +export let twin1Val: string = record1[twin1] satisfies "twin"; +>twin1Val : Symbol(twin1Val, Decl(registeredSymbolPropertyAccess.ts, 15, 10)) +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) +>twin1 : Symbol(twin1, Decl(registeredSymbolPropertyAccess.ts, 1, 12)) + +export let twin2Val: string = record1[twin2] satisfies "twin"; +>twin2Val : Symbol(twin2Val, Decl(registeredSymbolPropertyAccess.ts, 16, 10)) +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) + +export let unique1Val: string = record1[unique1] satisfies "unique1"; +>unique1Val : Symbol(unique1Val, Decl(registeredSymbolPropertyAccess.ts, 17, 10)) +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + +export let unique2Val: string = record1[unique2] satisfies "unique2"; +>unique2Val : Symbol(unique2Val, Decl(registeredSymbolPropertyAccess.ts, 18, 10)) +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) + +export const record2 = { +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) + + ...record1, +>record1 : Symbol(record1, Decl(registeredSymbolPropertyAccess.ts, 8, 12)) + + [unique1]: "unique1New", +>[unique1] : Symbol([unique1], Decl(registeredSymbolPropertyAccess.ts, 21, 15)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + + [wellKnown]: "wellKnown", +>[wellKnown] : Symbol([wellKnown], Decl(registeredSymbolPropertyAccess.ts, 22, 28)) +>wellKnown : Symbol(wellKnown, Decl(registeredSymbolPropertyAccess.ts, 5, 12)) + +} as const; +>const : Symbol(const) + +singleVal = record2[single] satisfies "single"; +>singleVal : Symbol(singleVal, Decl(registeredSymbolPropertyAccess.ts, 14, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) + +twin1Val = record2[twin1] satisfies "twin"; +>twin1Val : Symbol(twin1Val, Decl(registeredSymbolPropertyAccess.ts, 15, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>twin1 : Symbol(twin1, Decl(registeredSymbolPropertyAccess.ts, 1, 12)) + +twin2Val = record2[twin2] satisfies "twin"; +>twin2Val : Symbol(twin2Val, Decl(registeredSymbolPropertyAccess.ts, 16, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) + +unique1Val = record2[unique1] satisfies "unique1New"; +>unique1Val : Symbol(unique1Val, Decl(registeredSymbolPropertyAccess.ts, 17, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + +unique2Val = record2[unique2] satisfies "unique2"; +>unique2Val : Symbol(unique2Val, Decl(registeredSymbolPropertyAccess.ts, 18, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) + +export let wellKnownVal: string = record2[wellKnown] satisfies "wellKnown"; +>wellKnownVal : Symbol(wellKnownVal, Decl(registeredSymbolPropertyAccess.ts, 30, 10)) +>record2 : Symbol(record2, Decl(registeredSymbolPropertyAccess.ts, 20, 12)) +>wellKnown : Symbol(wellKnown, Decl(registeredSymbolPropertyAccess.ts, 5, 12)) + +export const record3 = { +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) + + [single]: "single", +>[single] : Symbol([single], Decl(registeredSymbolPropertyAccess.ts, 32, 24)) +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) + + [twin2]: "twin", +>[twin2] : Symbol([twin2], Decl(registeredSymbolPropertyAccess.ts, 33, 23)) +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) + + [unique1]: "unique1", +>[unique1] : Symbol([unique1], Decl(registeredSymbolPropertyAccess.ts, 34, 20)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + + [unique2]: "unique2", +>[unique2] : Symbol([unique2], Decl(registeredSymbolPropertyAccess.ts, 35, 25)) +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) + + [wellKnown]: "wellKnown", +>[wellKnown] : Symbol([wellKnown], Decl(registeredSymbolPropertyAccess.ts, 36, 25)) +>wellKnown : Symbol(wellKnown, Decl(registeredSymbolPropertyAccess.ts, 5, 12)) + +} as const; +>const : Symbol(const) + +singleVal = record3[single] satisfies "single"; +>singleVal : Symbol(singleVal, Decl(registeredSymbolPropertyAccess.ts, 14, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>single : Symbol(single, Decl(registeredSymbolPropertyAccess.ts, 0, 12)) + +twin1Val = record3[twin1] satisfies "twin"; +>twin1Val : Symbol(twin1Val, Decl(registeredSymbolPropertyAccess.ts, 15, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>twin1 : Symbol(twin1, Decl(registeredSymbolPropertyAccess.ts, 1, 12)) + +twin2Val = record3[twin2] satisfies "twin"; +>twin2Val : Symbol(twin2Val, Decl(registeredSymbolPropertyAccess.ts, 16, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>twin2 : Symbol(twin2, Decl(registeredSymbolPropertyAccess.ts, 2, 12)) + +unique1Val = record3[unique1] satisfies "unique1"; +>unique1Val : Symbol(unique1Val, Decl(registeredSymbolPropertyAccess.ts, 17, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>unique1 : Symbol(unique1, Decl(registeredSymbolPropertyAccess.ts, 3, 12)) + +unique2Val = record3[unique2] satisfies "unique2"; +>unique2Val : Symbol(unique2Val, Decl(registeredSymbolPropertyAccess.ts, 18, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>unique2 : Symbol(unique2, Decl(registeredSymbolPropertyAccess.ts, 4, 12)) + +wellKnownVal = record3[wellKnown] satisfies "wellKnown"; +>wellKnownVal : Symbol(wellKnownVal, Decl(registeredSymbolPropertyAccess.ts, 30, 10)) +>record3 : Symbol(record3, Decl(registeredSymbolPropertyAccess.ts, 32, 12)) +>wellKnown : Symbol(wellKnown, Decl(registeredSymbolPropertyAccess.ts, 5, 12)) + +export const record4 = { +>record4 : Symbol(record4, Decl(registeredSymbolPropertyAccess.ts, 46, 12)) + + [wellKnown2]: "wellKnown2", +>[wellKnown2] : Symbol([wellKnown2], Decl(registeredSymbolPropertyAccess.ts, 46, 24)) +>wellKnown2 : Symbol(wellKnown2, Decl(registeredSymbolPropertyAccess.ts, 6, 12)) + +} as const; +>const : Symbol(const) + +export let wellKnown2Val: string = record4[wellKnown2] satisfies "wellKnown2"; +>wellKnown2Val : Symbol(wellKnown2Val, Decl(registeredSymbolPropertyAccess.ts, 49, 10)) +>record4 : Symbol(record4, Decl(registeredSymbolPropertyAccess.ts, 46, 12)) +>wellKnown2 : Symbol(wellKnown2, Decl(registeredSymbolPropertyAccess.ts, 6, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.types b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.types new file mode 100644 index 0000000000000..06cb06b09d07a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/registeredSymbolPropertyAccess.types @@ -0,0 +1,275 @@ +//// [tests/cases/compiler/registeredSymbolPropertyAccess.ts] //// + +=== registeredSymbolPropertyAccess.ts === +export const single = Symbol.for("single"); +>single : RegisteredSymbol<"single"> +>Symbol.for("single") : RegisteredSymbol<"single"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"single" : "single" + +export const twin1 = Symbol.for("twin"); +>twin1 : RegisteredSymbol<"twin"> +>Symbol.for("twin") : RegisteredSymbol<"twin"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"twin" : "twin" + +export const twin2 = Symbol.for("twin"); +>twin2 : RegisteredSymbol<"twin"> +>Symbol.for("twin") : RegisteredSymbol<"twin"> +>Symbol.for : (key: Key) => RegisteredSymbol +>Symbol : SymbolConstructor +>for : (key: Key) => RegisteredSymbol +>"twin" : "twin" + +export const unique1 = Symbol("unique"); +>unique1 : unique symbol +>Symbol("unique") : unique symbol +>Symbol : SymbolConstructor +>"unique" : "unique" + +export const unique2 = Symbol("unique"); +>unique2 : unique symbol +>Symbol("unique") : unique symbol +>Symbol : SymbolConstructor +>"unique" : "unique" + +export const wellKnown = Symbol.match; +>wellKnown : unique symbol +>Symbol.match : unique symbol +>Symbol : SymbolConstructor +>match : unique symbol + +export const wellKnown2 = Symbol.toStringTag; +>wellKnown2 : unique symbol +>Symbol.toStringTag : unique symbol +>Symbol : SymbolConstructor +>toStringTag : unique symbol + +export const record1 = { +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>{ [single]: "single", [twin2]: "twin", [unique1]: "unique1", [unique2]: "unique2",} as const : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>{ [single]: "single", [twin2]: "twin", [unique1]: "unique1", [unique2]: "unique2",} : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } + + [single]: "single", +>[single] : "single" +>single : RegisteredSymbol<"single"> +>"single" : "single" + + [twin2]: "twin", +>[twin2] : "twin" +>twin2 : RegisteredSymbol<"twin"> +>"twin" : "twin" + + [unique1]: "unique1", +>[unique1] : "unique1" +>unique1 : unique symbol +>"unique1" : "unique1" + + [unique2]: "unique2", +>[unique2] : "unique2" +>unique2 : unique symbol +>"unique2" : "unique2" + +} as const; +export let singleVal: string = record1[single] satisfies "single"; +>singleVal : string +>record1[single] satisfies "single" : "single" +>record1[single] : "single" +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>single : RegisteredSymbol<"single"> + +export let twin1Val: string = record1[twin1] satisfies "twin"; +>twin1Val : string +>record1[twin1] satisfies "twin" : "twin" +>record1[twin1] : "twin" +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>twin1 : RegisteredSymbol<"twin"> + +export let twin2Val: string = record1[twin2] satisfies "twin"; +>twin2Val : string +>record1[twin2] satisfies "twin" : "twin" +>record1[twin2] : "twin" +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>twin2 : RegisteredSymbol<"twin"> + +export let unique1Val: string = record1[unique1] satisfies "unique1"; +>unique1Val : string +>record1[unique1] satisfies "unique1" : "unique1" +>record1[unique1] : "unique1" +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>unique1 : unique symbol + +export let unique2Val: string = record1[unique2] satisfies "unique2"; +>unique2Val : string +>record1[unique2] satisfies "unique2" : "unique2" +>record1[unique2] : "unique2" +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } +>unique2 : unique symbol + +export const record2 = { +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>{ ...record1, [unique1]: "unique1New", [wellKnown]: "wellKnown",} as const : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>{ ...record1, [unique1]: "unique1New", [wellKnown]: "wellKnown",} : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } + + ...record1, +>record1 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; } + + [unique1]: "unique1New", +>[unique1] : "unique1New" +>unique1 : unique symbol +>"unique1New" : "unique1New" + + [wellKnown]: "wellKnown", +>[wellKnown] : "wellKnown" +>wellKnown : unique symbol +>"wellKnown" : "wellKnown" + +} as const; +singleVal = record2[single] satisfies "single"; +>singleVal = record2[single] satisfies "single" : "single" +>singleVal : string +>record2[single] satisfies "single" : "single" +>record2[single] : "single" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>single : RegisteredSymbol<"single"> + +twin1Val = record2[twin1] satisfies "twin"; +>twin1Val = record2[twin1] satisfies "twin" : "twin" +>twin1Val : string +>record2[twin1] satisfies "twin" : "twin" +>record2[twin1] : "twin" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>twin1 : RegisteredSymbol<"twin"> + +twin2Val = record2[twin2] satisfies "twin"; +>twin2Val = record2[twin2] satisfies "twin" : "twin" +>twin2Val : string +>record2[twin2] satisfies "twin" : "twin" +>record2[twin2] : "twin" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>twin2 : RegisteredSymbol<"twin"> + +unique1Val = record2[unique1] satisfies "unique1New"; +>unique1Val = record2[unique1] satisfies "unique1New" : "unique1New" +>unique1Val : string +>record2[unique1] satisfies "unique1New" : "unique1New" +>record2[unique1] : "unique1New" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>unique1 : unique symbol + +unique2Val = record2[unique2] satisfies "unique2"; +>unique2Val = record2[unique2] satisfies "unique2" : "unique2" +>unique2Val : string +>record2[unique2] satisfies "unique2" : "unique2" +>record2[unique2] : "unique2" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>unique2 : unique symbol + +export let wellKnownVal: string = record2[wellKnown] satisfies "wellKnown"; +>wellKnownVal : string +>record2[wellKnown] satisfies "wellKnown" : "wellKnown" +>record2[wellKnown] : "wellKnown" +>record2 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique2]: "unique2"; readonly [unique1]: "unique1New"; readonly [Symbol.match]: "wellKnown"; } +>wellKnown : unique symbol + +export const record3 = { +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>{ [single]: "single", [twin2]: "twin", [unique1]: "unique1", [unique2]: "unique2", [wellKnown]: "wellKnown",} as const : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>{ [single]: "single", [twin2]: "twin", [unique1]: "unique1", [unique2]: "unique2", [wellKnown]: "wellKnown",} : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } + + [single]: "single", +>[single] : "single" +>single : RegisteredSymbol<"single"> +>"single" : "single" + + [twin2]: "twin", +>[twin2] : "twin" +>twin2 : RegisteredSymbol<"twin"> +>"twin" : "twin" + + [unique1]: "unique1", +>[unique1] : "unique1" +>unique1 : unique symbol +>"unique1" : "unique1" + + [unique2]: "unique2", +>[unique2] : "unique2" +>unique2 : unique symbol +>"unique2" : "unique2" + + [wellKnown]: "wellKnown", +>[wellKnown] : "wellKnown" +>wellKnown : unique symbol +>"wellKnown" : "wellKnown" + +} as const; +singleVal = record3[single] satisfies "single"; +>singleVal = record3[single] satisfies "single" : "single" +>singleVal : string +>record3[single] satisfies "single" : "single" +>record3[single] : "single" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>single : RegisteredSymbol<"single"> + +twin1Val = record3[twin1] satisfies "twin"; +>twin1Val = record3[twin1] satisfies "twin" : "twin" +>twin1Val : string +>record3[twin1] satisfies "twin" : "twin" +>record3[twin1] : "twin" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>twin1 : RegisteredSymbol<"twin"> + +twin2Val = record3[twin2] satisfies "twin"; +>twin2Val = record3[twin2] satisfies "twin" : "twin" +>twin2Val : string +>record3[twin2] satisfies "twin" : "twin" +>record3[twin2] : "twin" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>twin2 : RegisteredSymbol<"twin"> + +unique1Val = record3[unique1] satisfies "unique1"; +>unique1Val = record3[unique1] satisfies "unique1" : "unique1" +>unique1Val : string +>record3[unique1] satisfies "unique1" : "unique1" +>record3[unique1] : "unique1" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>unique1 : unique symbol + +unique2Val = record3[unique2] satisfies "unique2"; +>unique2Val = record3[unique2] satisfies "unique2" : "unique2" +>unique2Val : string +>record3[unique2] satisfies "unique2" : "unique2" +>record3[unique2] : "unique2" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>unique2 : unique symbol + +wellKnownVal = record3[wellKnown] satisfies "wellKnown"; +>wellKnownVal = record3[wellKnown] satisfies "wellKnown" : "wellKnown" +>wellKnownVal : string +>record3[wellKnown] satisfies "wellKnown" : "wellKnown" +>record3[wellKnown] : "wellKnown" +>record3 : { readonly [single]: "single"; readonly [twin2]: "twin"; readonly [unique1]: "unique1"; readonly [unique2]: "unique2"; readonly [Symbol.match]: "wellKnown"; } +>wellKnown : unique symbol + +export const record4 = { +>record4 : { readonly [Symbol.toStringTag]: "wellKnown2"; } +>{ [wellKnown2]: "wellKnown2",} as const : { readonly [Symbol.toStringTag]: "wellKnown2"; } +>{ [wellKnown2]: "wellKnown2",} : { readonly [Symbol.toStringTag]: "wellKnown2"; } + + [wellKnown2]: "wellKnown2", +>[wellKnown2] : "wellKnown2" +>wellKnown2 : unique symbol +>"wellKnown2" : "wellKnown2" + +} as const; +export let wellKnown2Val: string = record4[wellKnown2] satisfies "wellKnown2"; +>wellKnown2Val : string +>record4[wellKnown2] satisfies "wellKnown2" : "wellKnown2" +>record4[wellKnown2] : "wellKnown2" +>record4 : { readonly [Symbol.toStringTag]: "wellKnown2"; } +>wellKnown2 : unique symbol + diff --git a/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.symbols b/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.symbols new file mode 100644 index 0000000000000..ef40851edcdde --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.symbols @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/uniqueSymbolConstLikeWidening.ts] //// + +=== uniqueSymbolConstLikeWidening.ts === +const us = Symbol.match; +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const us2 = us; +>us2 : Symbol(us2, Decl(uniqueSymbolConstLikeWidening.ts, 1, 5)) +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) + +let widened = us; +>widened : Symbol(widened, Decl(uniqueSymbolConstLikeWidening.ts, 2, 3)) +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) + +let asserted = us as const; +>asserted : Symbol(asserted, Decl(uniqueSymbolConstLikeWidening.ts, 3, 3)) +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) +>const : Symbol(const) + +let sameAsSource: typeof us = us2; +>sameAsSource : Symbol(sameAsSource, Decl(uniqueSymbolConstLikeWidening.ts, 5, 3)) +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) +>us2 : Symbol(us2, Decl(uniqueSymbolConstLikeWidening.ts, 1, 5)) + +let sameAsAsserted: typeof us = asserted; +>sameAsAsserted : Symbol(sameAsAsserted, Decl(uniqueSymbolConstLikeWidening.ts, 6, 3)) +>us : Symbol(us, Decl(uniqueSymbolConstLikeWidening.ts, 0, 5)) +>asserted : Symbol(asserted, Decl(uniqueSymbolConstLikeWidening.ts, 3, 3)) + +let symbolFromConst: symbol = us2; +>symbolFromConst : Symbol(symbolFromConst, Decl(uniqueSymbolConstLikeWidening.ts, 7, 3)) +>us2 : Symbol(us2, Decl(uniqueSymbolConstLikeWidening.ts, 1, 5)) + +let symbolFromAsserted: symbol = asserted; +>symbolFromAsserted : Symbol(symbolFromAsserted, Decl(uniqueSymbolConstLikeWidening.ts, 8, 3)) +>asserted : Symbol(asserted, Decl(uniqueSymbolConstLikeWidening.ts, 3, 3)) + diff --git a/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.types b/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.types new file mode 100644 index 0000000000000..17cdf95bf699a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/uniqueSymbolConstLikeWidening.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/uniqueSymbolConstLikeWidening.ts] //// + +=== uniqueSymbolConstLikeWidening.ts === +const us = Symbol.match; +>us : unique symbol +>Symbol.match : unique symbol +>Symbol : SymbolConstructor +>match : unique symbol + +const us2 = us; +>us2 : unique symbol +>us : unique symbol + +let widened = us; +>widened : symbol +>us : unique symbol + +let asserted = us as const; +>asserted : unique symbol +>us as const : unique symbol +>us : unique symbol + +let sameAsSource: typeof us = us2; +>sameAsSource : unique symbol +>us : unique symbol +>us2 : unique symbol + +let sameAsAsserted: typeof us = asserted; +>sameAsAsserted : unique symbol +>us : unique symbol +>asserted : unique symbol + +let symbolFromConst: symbol = us2; +>symbolFromConst : symbol +>us2 : unique symbol + +let symbolFromAsserted: symbol = asserted; +>symbolFromAsserted : symbol +>asserted : unique symbol + diff --git a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess1.types b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess1.types index 5f5e70552c541..ac2d28394106c 100644 --- a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess1.types +++ b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess1.types @@ -3,10 +3,10 @@ === superSymbolIndexedAccess1.ts === var symbol = Symbol.for('myThing'); >symbol : symbol ->Symbol.for('myThing') : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for('myThing') : RegisteredSymbol<"myThing"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >'myThing' : "myThing" class Foo { diff --git a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess3.types b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess3.types index 5e1eb518d970b..0b6db132cbd4b 100644 --- a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess3.types +++ b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess3.types @@ -3,10 +3,10 @@ === superSymbolIndexedAccess3.ts === var symbol = Symbol.for('myThing'); >symbol : symbol ->Symbol.for('myThing') : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for('myThing') : RegisteredSymbol<"myThing"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >'myThing' : "myThing" class Foo { diff --git a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess4.types b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess4.types index 88170be4341f9..7aa1497a54204 100644 --- a/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess4.types +++ b/tsc/testdata/baselines/reference/conformance/superSymbolIndexedAccess4.types @@ -3,10 +3,10 @@ === superSymbolIndexedAccess4.ts === var symbol = Symbol.for('myThing'); >symbol : symbol ->Symbol.for('myThing') : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for('myThing') : RegisteredSymbol<"myThing"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >'myThing' : "myThing" class Bar { diff --git a/tsc/testdata/baselines/reference/conformance/symbolProperty53.errors.txt b/tsc/testdata/baselines/reference/conformance/symbolProperty53.errors.txt index 096d453cbd652..9ca661b922dc9 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolProperty53.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/symbolProperty53.errors.txt @@ -1,5 +1,5 @@ symbolProperty53.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. -symbolProperty53.ts(5,5): error TS2538: Type '(key: string) => symbol' cannot be used as an index type. +symbolProperty53.ts(5,5): error TS2538: Type '(key: Key) => RegisteredSymbol' cannot be used as an index type. ==== symbolProperty53.ts (2 errors) ==== @@ -11,4 +11,4 @@ symbolProperty53.ts(5,5): error TS2538: Type '(key: string) => symbol' cannot be obj[Symbol.for]; ~~~~~~~~~~ -!!! error TS2538: Type '(key: string) => symbol' cannot be used as an index type. \ No newline at end of file +!!! error TS2538: Type '(key: Key) => RegisteredSymbol' cannot be used as an index type. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/symbolProperty53.types b/tsc/testdata/baselines/reference/conformance/symbolProperty53.types index 92d5254c63f6c..036ca190ff45f 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolProperty53.types +++ b/tsc/testdata/baselines/reference/conformance/symbolProperty53.types @@ -7,9 +7,9 @@ var obj = { [Symbol.for]: 0 >[Symbol.for] : number ->Symbol.for : (key: string) => symbol +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >0 : 0 }; @@ -17,7 +17,7 @@ var obj = { obj[Symbol.for]; >obj[Symbol.for] : any >obj : {} ->Symbol.for : (key: string) => symbol +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol diff --git a/tsc/testdata/baselines/reference/conformance/symbolType10.types b/tsc/testdata/baselines/reference/conformance/symbolType10.types index d42b177f8e738..a647762dc5e4b 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType10.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType10.types @@ -3,10 +3,10 @@ === symbolType10.ts === var s = Symbol.for("bitwise"); >s : symbol ->Symbol.for("bitwise") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("bitwise") : RegisteredSymbol<"bitwise"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"bitwise" : "bitwise" s & s; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType11.types b/tsc/testdata/baselines/reference/conformance/symbolType11.types index ce5139c311275..1e5390bb6d54b 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType11.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType11.types @@ -3,10 +3,10 @@ === symbolType11.ts === var s = Symbol.for("logical"); >s : symbol ->Symbol.for("logical") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("logical") : RegisteredSymbol<"logical"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"logical" : "logical" s && s; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType12.types b/tsc/testdata/baselines/reference/conformance/symbolType12.types index 476e718bbc6fb..a2942c4339047 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType12.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType12.types @@ -3,10 +3,10 @@ === symbolType12.ts === var s = Symbol.for("assign"); >s : symbol ->Symbol.for("assign") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("assign") : RegisteredSymbol<"assign"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"assign" : "assign" var str = ""; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType4.types b/tsc/testdata/baselines/reference/conformance/symbolType4.types index 7d365d19d4357..04897eaa14de5 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType4.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType4.types @@ -3,10 +3,10 @@ === symbolType4.ts === var s = Symbol.for("postfix"); >s : symbol ->Symbol.for("postfix") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("postfix") : RegisteredSymbol<"postfix"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"postfix" : "postfix" s++; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType5.types b/tsc/testdata/baselines/reference/conformance/symbolType5.types index 67d5c757a9a7a..a4a3f9a69d603 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType5.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType5.types @@ -3,10 +3,10 @@ === symbolType5.ts === var s = Symbol.for("multiply"); >s : symbol ->Symbol.for("multiply") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("multiply") : RegisteredSymbol<"multiply"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"multiply" : "multiply" s * s; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType6.types b/tsc/testdata/baselines/reference/conformance/symbolType6.types index 5010072293994..6176251c5626e 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType6.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType6.types @@ -3,10 +3,10 @@ === symbolType6.ts === var s = Symbol.for("add"); >s : symbol ->Symbol.for("add") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("add") : RegisteredSymbol<"add"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"add" : "add" var a: any; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType7.types b/tsc/testdata/baselines/reference/conformance/symbolType7.types index 5865a8c28fbf6..b98e3c9071d88 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType7.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType7.types @@ -3,10 +3,10 @@ === symbolType7.ts === var s = Symbol.for("shift"); >s : symbol ->Symbol.for("shift") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("shift") : RegisteredSymbol<"shift"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"shift" : "shift" s << s; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType8.types b/tsc/testdata/baselines/reference/conformance/symbolType8.types index 148e8699636c2..2178d5e63b0cf 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType8.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType8.types @@ -3,10 +3,10 @@ === symbolType8.ts === var s = Symbol.for("compare"); >s : symbol ->Symbol.for("compare") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("compare") : RegisteredSymbol<"compare"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"compare" : "compare" s < s; diff --git a/tsc/testdata/baselines/reference/conformance/symbolType9.types b/tsc/testdata/baselines/reference/conformance/symbolType9.types index 7e2b06a1c5d02..39308803347ba 100644 --- a/tsc/testdata/baselines/reference/conformance/symbolType9.types +++ b/tsc/testdata/baselines/reference/conformance/symbolType9.types @@ -3,10 +3,10 @@ === symbolType9.ts === var s = Symbol.for("equal"); >s : symbol ->Symbol.for("equal") : symbol ->Symbol.for : (key: string) => symbol +>Symbol.for("equal") : RegisteredSymbol<"equal"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"equal" : "equal" s == s; diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbols.types b/tsc/testdata/baselines/reference/conformance/uniqueSymbols.types index 1478ffc517f2a..5d5a22b6de7fc 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbols.types +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbols.types @@ -29,7 +29,7 @@ const constTypeAndCall: unique symbol = Symbol(); // declaration from initializer const constInitToConstCall = constCall; ->constInitToConstCall : symbol +>constInitToConstCall : unique symbol >constCall : unique symbol const constInitToLetCall = letCall; @@ -41,7 +41,7 @@ const constInitToVarCall = varCall; >varCall : symbol const constInitToConstDeclAmbient = constType; ->constInitToConstDeclAmbient : symbol +>constInitToConstDeclAmbient : unique symbol >constType : unique symbol let letInitToConstCall = constCall; @@ -201,19 +201,19 @@ declare const c: C; >c : C const constInitToCReadonlyStaticCall = C.readonlyStaticCall; ->constInitToCReadonlyStaticCall : symbol +>constInitToCReadonlyStaticCall : unique symbol >C.readonlyStaticCall : unique symbol >C : typeof C >readonlyStaticCall : unique symbol const constInitToCReadonlyStaticType = C.readonlyStaticType; ->constInitToCReadonlyStaticType : symbol +>constInitToCReadonlyStaticType : unique symbol >C.readonlyStaticType : unique symbol >C : typeof C >readonlyStaticType : unique symbol const constInitToCReadonlyStaticTypeAndCall = C.readonlyStaticTypeAndCall; ->constInitToCReadonlyStaticTypeAndCall : symbol +>constInitToCReadonlyStaticTypeAndCall : unique symbol >C.readonlyStaticTypeAndCall : unique symbol >C : typeof C >readonlyStaticTypeAndCall : unique symbol @@ -311,7 +311,7 @@ declare const i: I; >i : I const constInitToIReadonlyType = i.readonlyType; ->constInitToIReadonlyType : symbol +>constInitToIReadonlyType : unique symbol >i.readonlyType : unique symbol >i : I >readonlyType : unique symbol @@ -349,13 +349,13 @@ declare const l: L; >l : L const constInitToLReadonlyType = l.readonlyType; ->constInitToLReadonlyType : symbol +>constInitToLReadonlyType : unique symbol >l.readonlyType : unique symbol >l : L >readonlyType : unique symbol const constInitToLReadonlyNestedType = l.nested.readonlyNestedType; ->constInitToLReadonlyNestedType : symbol +>constInitToLReadonlyNestedType : unique symbol >l.nested.readonlyNestedType : unique symbol >l.nested : { readonly readonlyNestedType: unique symbol; } >l : L @@ -536,17 +536,17 @@ class C0 { >C0 : C0 static readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol static readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol static readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" @@ -568,17 +568,17 @@ class C0 { >"s" : "s" readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.js b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.js index df669ec3b1c74..08785dfcc7c2e 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.js +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.js @@ -415,10 +415,10 @@ declare let letCall: symbol; declare var varCall: symbol; declare const constType: unique symbol; declare const constTypeAndCall: unique symbol; -declare const constInitToConstCall: symbol; +declare const constInitToConstCall: typeof constCall; declare const constInitToLetCall: symbol; declare const constInitToVarCall: symbol; -declare const constInitToConstDeclAmbient: symbol; +declare const constInitToConstDeclAmbient: typeof constType; declare let letInitToConstCall: symbol; declare let letInitToLetCall: symbol; declare let letInitToVarCall: symbol; @@ -452,9 +452,9 @@ declare class C { readwriteCall: symbol; } declare const c: C; -declare const constInitToCReadonlyStaticCall: symbol; -declare const constInitToCReadonlyStaticType: symbol; -declare const constInitToCReadonlyStaticTypeAndCall: symbol; +declare const constInitToCReadonlyStaticCall: typeof C.readonlyStaticCall; +declare const constInitToCReadonlyStaticType: typeof C.readonlyStaticType; +declare const constInitToCReadonlyStaticTypeAndCall: typeof C.readonlyStaticTypeAndCall; declare const constInitToCReadwriteStaticCall: symbol; declare const constInitToCReadonlyStaticCallWithTypeQuery: typeof C.readonlyStaticCall; declare const constInitToCReadonlyStaticTypeWithTypeQuery: typeof C.readonlyStaticType; @@ -470,7 +470,7 @@ interface I { readonly readonlyType: unique symbol; } declare const i: I; -declare const constInitToIReadonlyType: symbol; +declare const constInitToIReadonlyType: I["readonlyType"]; declare const constInitToIReadonlyTypeWithTypeQuery: typeof i.readonlyType; declare const constInitToIReadonlyTypeWithIndexedAccess: I["readonlyType"]; type L = { @@ -480,8 +480,8 @@ type L = { }; }; declare const l: L; -declare const constInitToLReadonlyType: symbol; -declare const constInitToLReadonlyNestedType: symbol; +declare const constInitToLReadonlyType: typeof l.readonlyType; +declare const constInitToLReadonlyNestedType: typeof l.nested.readonlyNestedType; declare const constInitToLReadonlyTypeWithTypeQuery: typeof l.readonlyType; declare const constInitToLReadonlyNestedTypeWithTypeQuery: typeof l.nested.readonlyNestedType; declare const constInitToLReadonlyTypeWithIndexedAccess: L["readonlyType"]; @@ -510,15 +510,15 @@ declare const o2: { method5(p?: symbol): symbol; }; declare class C0 { - static readonly a: symbol; - static readonly b: symbol; - static readonly c: symbol; + static readonly a: typeof s; + static readonly b: typeof N.s; + static readonly c: typeof N.s; static d: symbol; static e: symbol; static f: symbol; - readonly a: symbol; - readonly b: symbol; - readonly c: symbol; + readonly a: typeof s; + readonly b: typeof N.s; + readonly c: typeof N.s; d: symbol; e: symbol; f: symbol; diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.types b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.types index 5f22b96c2573c..82cd1c8837849 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.types +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsDeclarations.types @@ -29,7 +29,7 @@ const constTypeAndCall: unique symbol = Symbol(); // declaration from initializer const constInitToConstCall = constCall; ->constInitToConstCall : symbol +>constInitToConstCall : unique symbol >constCall : unique symbol const constInitToLetCall = letCall; @@ -41,7 +41,7 @@ const constInitToVarCall = varCall; >varCall : symbol const constInitToConstDeclAmbient = constType; ->constInitToConstDeclAmbient : symbol +>constInitToConstDeclAmbient : unique symbol >constType : unique symbol let letInitToConstCall = constCall; @@ -194,19 +194,19 @@ declare const c: C; >c : C const constInitToCReadonlyStaticCall = C.readonlyStaticCall; ->constInitToCReadonlyStaticCall : symbol +>constInitToCReadonlyStaticCall : unique symbol >C.readonlyStaticCall : unique symbol >C : typeof C >readonlyStaticCall : unique symbol const constInitToCReadonlyStaticType = C.readonlyStaticType; ->constInitToCReadonlyStaticType : symbol +>constInitToCReadonlyStaticType : unique symbol >C.readonlyStaticType : unique symbol >C : typeof C >readonlyStaticType : unique symbol const constInitToCReadonlyStaticTypeAndCall = C.readonlyStaticTypeAndCall; ->constInitToCReadonlyStaticTypeAndCall : symbol +>constInitToCReadonlyStaticTypeAndCall : unique symbol >C.readonlyStaticTypeAndCall : unique symbol >C : typeof C >readonlyStaticTypeAndCall : unique symbol @@ -304,7 +304,7 @@ declare const i: I; >i : I const constInitToIReadonlyType = i.readonlyType; ->constInitToIReadonlyType : symbol +>constInitToIReadonlyType : unique symbol >i.readonlyType : unique symbol >i : I >readonlyType : unique symbol @@ -342,13 +342,13 @@ declare const l: L; >l : L const constInitToLReadonlyType = l.readonlyType; ->constInitToLReadonlyType : symbol +>constInitToLReadonlyType : unique symbol >l.readonlyType : unique symbol >l : L >readonlyType : unique symbol const constInitToLReadonlyNestedType = l.nested.readonlyNestedType; ->constInitToLReadonlyNestedType : symbol +>constInitToLReadonlyNestedType : unique symbol >l.nested.readonlyNestedType : unique symbol >l.nested : { readonly readonlyNestedType: unique symbol; } >l : L @@ -529,17 +529,17 @@ class C0 { >C0 : C0 static readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol static readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol static readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" @@ -561,17 +561,17 @@ class C0 { >"s" : "s" readonly a = s; ->a : symbol +>a : unique symbol >s : unique symbol readonly b = N.s; ->b : symbol +>b : unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol readonly c = N["s"]; ->c : symbol +>c : unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.errors.txt b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.errors.txt index 9c200fee5b475..dbf1dda62238a 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.errors.txt @@ -1,13 +1,17 @@ +uniqueSymbolsPropertyNames.ts(21,21): error TS2352: Conversion of type '{ equal: RegisteredSymbol<"equal">; }' to type 'OpTypes' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + Types of property 'equal' are incompatible. + Type 'RegisteredSymbol<"equal">' is not comparable to type 'unique symbol'. uniqueSymbolsPropertyNames.ts(27,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(28,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(33,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(38,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(43,3): error TS1117: An object literal cannot have multiple properties with the same name. +uniqueSymbolsPropertyNames.ts(44,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(45,3): error TS1117: An object literal cannot have multiple properties with the same name. uniqueSymbolsPropertyNames.ts(49,3): error TS2300: Duplicate identifier '[uniqueSymbol0]'. uniqueSymbolsPropertyNames.ts(50,3): error TS2300: Duplicate identifier '[uniqueSymbol0]'. -uniqueSymbolsPropertyNames.ts(51,3): error TS2300: Duplicate identifier '[uniqueSymbol1]'. -uniqueSymbolsPropertyNames.ts(52,3): error TS2300: Duplicate identifier '[uniqueSymbol1]'. +uniqueSymbolsPropertyNames.ts(51,3): error TS2300: Duplicate identifier '[uniqueSymbol0]'. +uniqueSymbolsPropertyNames.ts(52,3): error TS2300: Duplicate identifier '[uniqueSymbol0]'. uniqueSymbolsPropertyNames.ts(56,3): error TS2300: Duplicate identifier '[OpNamespace.equal]'. uniqueSymbolsPropertyNames.ts(57,3): error TS2300: Duplicate identifier '[OpNamespace.equal]'. uniqueSymbolsPropertyNames.ts(61,3): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. @@ -16,7 +20,7 @@ uniqueSymbolsPropertyNames.ts(63,3): error TS1166: A computed property name in a uniqueSymbolsPropertyNames.ts(64,3): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. -==== uniqueSymbolsPropertyNames.ts (16 errors) ==== +==== uniqueSymbolsPropertyNames.ts (18 errors) ==== interface OpTypes { readonly equal: unique symbol; } @@ -38,8 +42,14 @@ uniqueSymbolsPropertyNames.ts(64,3): error TS1166: A computed property name in a } const Op: OpTypes = { + ~ equal: Symbol.for("equal"), + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } as OpTypes; + ~~~~~~~~~~~~ +!!! error TS2352: Conversion of type '{ equal: RegisteredSymbol<"equal">; }' to type 'OpTypes' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. +!!! error TS2352: Types of property 'equal' are incompatible. +!!! error TS2352: Type 'RegisteredSymbol<"equal">' is not comparable to type 'unique symbol'. const t0 = { equal: "first", @@ -71,6 +81,8 @@ uniqueSymbolsPropertyNames.ts(64,3): error TS1166: A computed property name in a ~~~~~~~~~~~~~~~~~~~~ !!! error TS1117: An object literal cannot have multiple properties with the same name. [getUniqueSymbol1()]: "first", + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS1117: An object literal cannot have multiple properties with the same name. [getUniqueSymbol1()]: "last", ~~~~~~~~~~~~~~~~~~~~ !!! error TS1117: An object literal cannot have multiple properties with the same name. @@ -85,10 +97,10 @@ uniqueSymbolsPropertyNames.ts(64,3): error TS1166: A computed property name in a !!! error TS2300: Duplicate identifier '[uniqueSymbol0]'. [uniqueSymbol1] = "first"; ~~~~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier '[uniqueSymbol1]'. +!!! error TS2300: Duplicate identifier '[uniqueSymbol0]'. [uniqueSymbol1] = "last"; ~~~~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier '[uniqueSymbol1]'. +!!! error TS2300: Duplicate identifier '[uniqueSymbol0]'. } class Cls2 { diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.symbols b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.symbols index 05372d8887654..d2395ecd0d3b1 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.symbols +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.symbols @@ -131,19 +131,19 @@ class Cls1 { >Cls1 : Symbol(Cls1, Decl(uniqueSymbolsPropertyNames.ts, 45, 2)) [uniqueSymbol0] = "first"; ->[uniqueSymbol0] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28)) +>[uniqueSymbol0] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28), Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) >uniqueSymbol0 : Symbol(uniqueSymbol0, Decl(uniqueSymbolsPropertyNames.ts, 8, 5)) [uniqueSymbol0] = "last"; ->[uniqueSymbol0] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28)) +>[uniqueSymbol0] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28), Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) >uniqueSymbol0 : Symbol(uniqueSymbol0, Decl(uniqueSymbolsPropertyNames.ts, 8, 5)) [uniqueSymbol1] = "first"; ->[uniqueSymbol1] : Symbol(Cls1[uniqueSymbol1], Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) +>[uniqueSymbol1] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28), Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) >uniqueSymbol1 : Symbol(uniqueSymbol1, Decl(uniqueSymbolsPropertyNames.ts, 9, 5)) [uniqueSymbol1] = "last"; ->[uniqueSymbol1] : Symbol(Cls1[uniqueSymbol1], Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) +>[uniqueSymbol1] : Symbol(Cls1[uniqueSymbol0], Decl(uniqueSymbolsPropertyNames.ts, 47, 12), Decl(uniqueSymbolsPropertyNames.ts, 48, 28), Decl(uniqueSymbolsPropertyNames.ts, 49, 27), Decl(uniqueSymbolsPropertyNames.ts, 50, 28)) >uniqueSymbol1 : Symbol(uniqueSymbol1, Decl(uniqueSymbolsPropertyNames.ts, 9, 5)) } diff --git a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.types b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.types index f3596c9f4fda0..1e452fc50db00 100644 --- a/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.types +++ b/tsc/testdata/baselines/reference/conformance/uniqueSymbolsPropertyNames.types @@ -14,49 +14,49 @@ namespace OpNamespace { } const uniqueSymbol0 = Symbol.for(""); ->uniqueSymbol0 : unique symbol ->Symbol.for("") : unique symbol ->Symbol.for : (key: string) => symbol +>uniqueSymbol0 : RegisteredSymbol<""> +>Symbol.for("") : RegisteredSymbol<""> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"" : "" const uniqueSymbol1 = Symbol.for(""); ->uniqueSymbol1 : unique symbol ->Symbol.for("") : unique symbol ->Symbol.for : (key: string) => symbol +>uniqueSymbol1 : RegisteredSymbol<""> +>Symbol.for("") : RegisteredSymbol<""> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"" : "" function getUniqueSymbol0(): typeof uniqueSymbol0 { >getUniqueSymbol0 : () => typeof uniqueSymbol0 ->uniqueSymbol0 : unique symbol +>uniqueSymbol0 : RegisteredSymbol<""> return uniqueSymbol0; ->uniqueSymbol0 : unique symbol +>uniqueSymbol0 : RegisteredSymbol<""> } function getUniqueSymbol1(): typeof uniqueSymbol1 { >getUniqueSymbol1 : () => typeof uniqueSymbol1 ->uniqueSymbol1 : unique symbol +>uniqueSymbol1 : RegisteredSymbol<""> return uniqueSymbol1; ->uniqueSymbol1 : unique symbol +>uniqueSymbol1 : RegisteredSymbol<""> } const Op: OpTypes = { >Op : OpTypes >{ equal: Symbol.for("equal"),} as OpTypes : OpTypes ->{ equal: Symbol.for("equal"),} : { equal: symbol; } +>{ equal: Symbol.for("equal"),} : { equal: RegisteredSymbol<"equal">; } equal: Symbol.for("equal"), ->equal : symbol ->Symbol.for("equal") : symbol ->Symbol.for : (key: string) => symbol +>equal : RegisteredSymbol<"equal"> +>Symbol.for("equal") : RegisteredSymbol<"equal"> +>Symbol.for : (key: Key) => RegisteredSymbol >Symbol : SymbolConstructor ->for : (key: string) => symbol +>for : (key: Key) => RegisteredSymbol >"equal" : "equal" } as OpTypes; @@ -121,30 +121,30 @@ const t2 = { }; const t3 = { ->t3 : { [uniqueSymbol0]: string; [uniqueSymbol1]: string; } ->{ [getUniqueSymbol0()]: "first", [getUniqueSymbol0()]: "last", [getUniqueSymbol1()]: "first", [getUniqueSymbol1()]: "last",} : { [uniqueSymbol0]: string; [uniqueSymbol1]: string; } +>t3 : { [K in RegisteredSymbol<"">]: string;} +>{ [getUniqueSymbol0()]: "first", [getUniqueSymbol0()]: "last", [getUniqueSymbol1()]: "first", [getUniqueSymbol1()]: "last",} : { [K in RegisteredSymbol<"">]: string;} [getUniqueSymbol0()]: "first", >[getUniqueSymbol0()] : string ->getUniqueSymbol0() : unique symbol +>getUniqueSymbol0() : RegisteredSymbol<""> >getUniqueSymbol0 : () => typeof uniqueSymbol0 >"first" : "first" [getUniqueSymbol0()]: "last", >[getUniqueSymbol0()] : string ->getUniqueSymbol0() : unique symbol +>getUniqueSymbol0() : RegisteredSymbol<""> >getUniqueSymbol0 : () => typeof uniqueSymbol0 >"last" : "last" [getUniqueSymbol1()]: "first", >[getUniqueSymbol1()] : string ->getUniqueSymbol1() : unique symbol +>getUniqueSymbol1() : RegisteredSymbol<""> >getUniqueSymbol1 : () => typeof uniqueSymbol1 >"first" : "first" [getUniqueSymbol1()]: "last", >[getUniqueSymbol1()] : string ->getUniqueSymbol1() : unique symbol +>getUniqueSymbol1() : RegisteredSymbol<""> >getUniqueSymbol1 : () => typeof uniqueSymbol1 >"last" : "last" @@ -155,22 +155,22 @@ class Cls1 { [uniqueSymbol0] = "first"; >[uniqueSymbol0] : string ->uniqueSymbol0 : unique symbol +>uniqueSymbol0 : RegisteredSymbol<""> >"first" : "first" [uniqueSymbol0] = "last"; >[uniqueSymbol0] : string ->uniqueSymbol0 : unique symbol +>uniqueSymbol0 : RegisteredSymbol<""> >"last" : "last" [uniqueSymbol1] = "first"; >[uniqueSymbol1] : string ->uniqueSymbol1 : unique symbol +>uniqueSymbol1 : RegisteredSymbol<""> >"first" : "first" [uniqueSymbol1] = "last"; >[uniqueSymbol1] : string ->uniqueSymbol1 : unique symbol +>uniqueSymbol1 : RegisteredSymbol<""> >"last" : "last" } @@ -197,25 +197,25 @@ class Cls3 { [getUniqueSymbol0()] = "first"; >[getUniqueSymbol0()] : string ->getUniqueSymbol0() : unique symbol +>getUniqueSymbol0() : RegisteredSymbol<""> >getUniqueSymbol0 : () => typeof uniqueSymbol0 >"first" : "first" [getUniqueSymbol0()] = "last"; >[getUniqueSymbol0()] : string ->getUniqueSymbol0() : unique symbol +>getUniqueSymbol0() : RegisteredSymbol<""> >getUniqueSymbol0 : () => typeof uniqueSymbol0 >"last" : "last" [getUniqueSymbol1()] = "first"; >[getUniqueSymbol1()] : string ->getUniqueSymbol1() : unique symbol +>getUniqueSymbol1() : RegisteredSymbol<""> >getUniqueSymbol1 : () => typeof uniqueSymbol1 >"first" : "first" [getUniqueSymbol1()] = "last"; >[getUniqueSymbol1()] : string ->getUniqueSymbol1() : unique symbol +>getUniqueSymbol1() : RegisteredSymbol<""> >getUniqueSymbol1 : () => typeof uniqueSymbol1 >"last" : "last" } diff --git a/tsc/testdata/tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts b/tsc/testdata/tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts new file mode 100644 index 0000000000000..563aaf1dadeb0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/registeredSymbolComputedNameDeclaration.ts @@ -0,0 +1,13 @@ +// @target: es2015 +// @declaration: true + +export const key = Symbol.for("abc"); +export function getKey(): typeof key { return key; } + +export const value = { + ordinary: 1, + [getKey()]: "text", + [Symbol.for("other")]: true, +}; + +export const readonlyValue = { [getKey()]: "fixed" } as const; diff --git a/tsc/testdata/tests/cases/compiler/registeredSymbolDeferredKey.ts b/tsc/testdata/tests/cases/compiler/registeredSymbolDeferredKey.ts new file mode 100644 index 0000000000000..c2f092d62adeb --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/registeredSymbolDeferredKey.ts @@ -0,0 +1,25 @@ +// @target: es2015 +// @strict: true +// @noUncheckedIndexedAccess: true +// @declaration: true +// @emitDeclarationOnly: true + +export function make(key: K) { + const registered = Symbol.for(key); + const widened: symbol = registered; + return registered; +} + +export function unreachable(key: never): never { + return Symbol.for(key); +} + +export function read(first: K, second: K) { + const firstKey = Symbol.for(first); + const record = { [firstKey]: "first" } as const; + const secondKey = Symbol.for(second); + const value: "first" = record[secondKey]; + return value; +} + +read<"a" | "b">("a", "b"); diff --git a/tsc/testdata/tests/cases/compiler/registeredSymbolGenericRelations.ts b/tsc/testdata/tests/cases/compiler/registeredSymbolGenericRelations.ts new file mode 100644 index 0000000000000..569354aaa0d7a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/registeredSymbolGenericRelations.ts @@ -0,0 +1,32 @@ +// @target: es2015 +// @strict: true +// @noEmit: true + +type Equal = + (() => T extends A ? 1 : 2) extends + (() => T extends B ? 1 : 2) ? true : false; + +declare function inferKey(value: RegisteredSymbol): K; +const inferred: "foo" = inferKey(Symbol.for("foo")); + +function simplify() { + const unionIsSymbol: true = null! as Equal | symbol, symbol>; + const intersectionIsRegistered: true = null! as Equal & symbol, RegisteredSymbol>; + return { unionIsSymbol, intersectionIsRegistered }; +} + +function widenKey(value: RegisteredSymbol): RegisteredSymbol<"foo" | "bar"> { + return value; +} + +function widenGeneric(value: RegisteredSymbol): RegisteredSymbol { + return value; +} + +function commonSymbol(value: RegisteredSymbol): symbol { + return value; +} + +function intersect(value: RegisteredSymbol): RegisteredSymbol & symbol { + return value; +} diff --git a/tsc/testdata/tests/cases/compiler/registeredSymbolIntrinsic.ts b/tsc/testdata/tests/cases/compiler/registeredSymbolIntrinsic.ts new file mode 100644 index 0000000000000..9fbe92c83951d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/registeredSymbolIntrinsic.ts @@ -0,0 +1,25 @@ +// @target: es2015 +// @noEmit: true + +const foo = Symbol.for("foo"); +const fooAgain = Symbol.for("foo"); +const bar = Symbol.for("bar"); + +let sameStringKey: typeof foo = fooAgain; +let registeredStringKey: RegisteredSymbol<"foo"> = foo; +let registeredBarKey: RegisteredSymbol<"bar"> = bar; +let widenedSymbol: symbol = foo; + +declare const key: string; +let registeredString: RegisteredSymbol = Symbol.for(key); +let dynamic = Symbol.for(key); +let invalidDynamicKey: typeof foo = dynamic; + +declare const unionKey: "foo" | "bar"; +let registeredUnion: RegisteredSymbol<"foo" | "bar"> = Symbol.for(unionKey); +let invalidUnionKey: typeof foo = registeredUnion; + +interface WithRegisteredKeys { + [foo]: string; + [bar]: number; +} diff --git a/tsc/testdata/tests/cases/compiler/registeredSymbolPropertyAccess.ts b/tsc/testdata/tests/cases/compiler/registeredSymbolPropertyAccess.ts new file mode 100644 index 0000000000000..5a9e7cc919c2b --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/registeredSymbolPropertyAccess.ts @@ -0,0 +1,54 @@ +// @target: es2015 +// @declaration: true +// @emitDeclarationOnly: true + +export const single = Symbol.for("single"); +export const twin1 = Symbol.for("twin"); +export const twin2 = Symbol.for("twin"); +export const unique1 = Symbol("unique"); +export const unique2 = Symbol("unique"); +export const wellKnown = Symbol.match; +export const wellKnown2 = Symbol.toStringTag; + +export const record1 = { + [single]: "single", + [twin2]: "twin", + [unique1]: "unique1", + [unique2]: "unique2", +} as const; +export let singleVal: string = record1[single] satisfies "single"; +export let twin1Val: string = record1[twin1] satisfies "twin"; +export let twin2Val: string = record1[twin2] satisfies "twin"; +export let unique1Val: string = record1[unique1] satisfies "unique1"; +export let unique2Val: string = record1[unique2] satisfies "unique2"; + +export const record2 = { + ...record1, + [unique1]: "unique1New", + [wellKnown]: "wellKnown", +} as const; +singleVal = record2[single] satisfies "single"; +twin1Val = record2[twin1] satisfies "twin"; +twin2Val = record2[twin2] satisfies "twin"; +unique1Val = record2[unique1] satisfies "unique1New"; +unique2Val = record2[unique2] satisfies "unique2"; +export let wellKnownVal: string = record2[wellKnown] satisfies "wellKnown"; + +export const record3 = { + [single]: "single", + [twin2]: "twin", + [unique1]: "unique1", + [unique2]: "unique2", + [wellKnown]: "wellKnown", +} as const; +singleVal = record3[single] satisfies "single"; +twin1Val = record3[twin1] satisfies "twin"; +twin2Val = record3[twin2] satisfies "twin"; +unique1Val = record3[unique1] satisfies "unique1"; +unique2Val = record3[unique2] satisfies "unique2"; +wellKnownVal = record3[wellKnown] satisfies "wellKnown"; + +export const record4 = { + [wellKnown2]: "wellKnown2", +} as const; +export let wellKnown2Val: string = record4[wellKnown2] satisfies "wellKnown2"; diff --git a/tsc/testdata/tests/cases/compiler/uniqueSymbolConstLikeWidening.ts b/tsc/testdata/tests/cases/compiler/uniqueSymbolConstLikeWidening.ts new file mode 100644 index 0000000000000..c7314629926cd --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/uniqueSymbolConstLikeWidening.ts @@ -0,0 +1,12 @@ +// @target: es2015 +// @noEmit: true + +const us = Symbol.match; +const us2 = us; +let widened = us; +let asserted = us as const; + +let sameAsSource: typeof us = us2; +let sameAsAsserted: typeof us = asserted; +let symbolFromConst: symbol = us2; +let symbolFromAsserted: symbol = asserted;