@@ -2497,7 +2497,7 @@ namespace ts {
24972497 return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
24982498 }
24992499 if (type.flags & TypeFlags.UniqueESSymbol) {
2500- return createESSymbolTypeNode( );
2500+ return createTypeOperatorNode(SyntaxKind.UniqueKeyword, createKeywordTypeNode(SyntaxKind.SymbolKeyword) );
25012501 }
25022502 if (type.flags & TypeFlags.Void) {
25032503 return createKeywordTypeNode(SyntaxKind.VoidKeyword);
@@ -3313,9 +3313,9 @@ namespace ts {
33133313 writeAnonymousType(<ObjectType>type, nextFlags);
33143314 }
33153315 else if (type.flags & TypeFlags.UniqueESSymbol) {
3316+ writeKeyword(writer, SyntaxKind.UniqueKeyword);
3317+ writeSpace(writer);
33163318 writeKeyword(writer, SyntaxKind.SymbolKeyword);
3317- writePunctuation(writer, SyntaxKind.OpenParenToken);
3318- writePunctuation(writer, SyntaxKind.CloseParenToken);
33193319 }
33203320 else if (type.flags & TypeFlags.StringOrNumberLiteral) {
33213321 writer.writeStringLiteral(literalTypeToString(<LiteralType>type));
@@ -4533,7 +4533,7 @@ namespace ts {
45334533 reportErrorsFromWidening(declaration, type);
45344534 }
45354535
4536- // always widen a unique ' symbol() ' type if the type was created for a different declaration.
4536+ // always widen a ' unique symbol' type if the type was created for a different declaration.
45374537 if (type.flags & TypeFlags.UniqueESSymbol && !declaration.type && type.symbol !== getSymbolOfNode(declaration)) {
45384538 type = esSymbolType;
45394539 }
@@ -5949,7 +5949,9 @@ namespace ts {
59495949 const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
59505950 const templateReadonly = !!type.declaration.readonlyToken;
59515951 const templateOptional = !!type.declaration.questionToken;
5952- if (type.declaration.typeParameter.constraint.kind === SyntaxKind.TypeOperator) {
5952+ const constraintDeclaration = type.declaration.typeParameter.constraint;
5953+ if (constraintDeclaration.kind === SyntaxKind.TypeOperator &&
5954+ (<TypeOperatorNode>constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) {
59535955 // We have a { [P in keyof T]: X }
59545956 for (const propertySymbol of getPropertiesOfType(modifiersType)) {
59555957 addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol);
@@ -6024,7 +6026,8 @@ namespace ts {
60246026 function getModifiersTypeFromMappedType(type: MappedType) {
60256027 if (!type.modifiersType) {
60266028 const constraintDeclaration = type.declaration.typeParameter.constraint;
6027- if (constraintDeclaration.kind === SyntaxKind.TypeOperator) {
6029+ if (constraintDeclaration.kind === SyntaxKind.TypeOperator &&
6030+ (<TypeOperatorNode>constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) {
60286031 // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
60296032 // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
60306033 // 'keyof T' to a literal union type and we can't recover T from that type.
@@ -7822,7 +7825,21 @@ namespace ts {
78227825 function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
78237826 const links = getNodeLinks(node);
78247827 if (!links.resolvedType) {
7825- links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
7828+ switch (node.operator) {
7829+ case SyntaxKind.KeyOfKeyword:
7830+ links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
7831+ break;
7832+ case SyntaxKind.UniqueKeyword:
7833+ if (node.type.kind === SyntaxKind.SymbolKeyword) {
7834+ const parent = skipParentheses(node).parent;
7835+ const symbol = getSymbolOfNode(parent);
7836+ links.resolvedType = symbol ? getUniqueESSymbolTypeForSymbol(symbol) : esSymbolType;
7837+ }
7838+ else {
7839+ links.resolvedType = unknownType;
7840+ }
7841+ break;
7842+ }
78267843 }
78277844 return links.resolvedType;
78287845 }
@@ -8226,21 +8243,6 @@ namespace ts {
82268243 return esSymbolType;
82278244 }
82288245
8229- function getTypeFromESSymbolTypeNode(node: ESSymbolTypeNode): Type {
8230- const links = getNodeLinks(node);
8231- if (!links.resolvedType) {
8232- const parent = skipParentheses(node).parent;
8233- const symbol = getSymbolOfNode(parent);
8234- if (symbol) {
8235- links.resolvedType = getUniqueESSymbolTypeForSymbol(symbol);
8236- }
8237- else {
8238- links.resolvedType = esSymbolType;
8239- }
8240- }
8241- return links.resolvedType;
8242- }
8243-
82448246 function getTypeFromJSDocVariadicType(node: JSDocVariadicType): Type {
82458247 const links = getNodeLinks(node);
82468248 if (!links.resolvedType) {
@@ -8300,8 +8302,6 @@ namespace ts {
83008302 return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode);
83018303 case SyntaxKind.LiteralType:
83028304 return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
8303- case SyntaxKind.ESSymbolType:
8304- return getTypeFromESSymbolTypeNode(<ESSymbolTypeNode>node);
83058305 case SyntaxKind.TypeReference:
83068306 return getTypeFromTypeReference(<TypeReferenceNode>node);
83078307 case SyntaxKind.TypePredicate:
@@ -17313,7 +17313,7 @@ namespace ts {
1731317313 type = checkAwaitedType(type, /*errorNode*/ func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
1731417314 }
1731517315
17316- // widen 'symbol() ' types when we infer the return type.
17316+ // widen 'unique symbol' types when we infer the return type.
1731717317 type = getWidenedTypeOfUniqueESSymbolType(type);
1731817318 }
1731917319 else {
@@ -17349,7 +17349,7 @@ namespace ts {
1734917349 // Return a union of the return expression types.
1735017350 type = getUnionType(types, /*subtypeReduction*/ true);
1735117351
17352- // widen 'symbol() ' types when we infer the return type.
17352+ // widen 'unique symbol' types when we infer the return type.
1735317353 type = getWidenedTypeOfUniqueESSymbolType(type);
1735417354
1735517355 if (functionFlags & FunctionFlags.Generator) { // AsyncGenerator function or Generator function
@@ -19428,8 +19428,9 @@ namespace ts {
1942819428 checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint);
1942919429 }
1943019430
19431- function checkSymbolType(node: ESSymbolTypeNode) {
19432- checkGrammarESSymbolTypeNode(node);
19431+ function checkTypeOperator(node: TypeOperatorNode) {
19432+ checkGrammarTypeOperatorNode(node);
19433+ checkSourceElement(node.type);
1943319434 }
1943419435
1943519436 function isPrivateWithinAmbient(node: Node): boolean {
@@ -23000,8 +23001,9 @@ namespace ts {
2300023001 case SyntaxKind.IntersectionType:
2300123002 return checkUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);
2300223003 case SyntaxKind.ParenthesizedType:
23003- case SyntaxKind.TypeOperator:
2300423004 return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
23005+ case SyntaxKind.TypeOperator:
23006+ return checkTypeOperator(<TypeOperatorNode>node);
2300523007 case SyntaxKind.JSDocAugmentsTag:
2300623008 return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
2300723009 case SyntaxKind.JSDocTypedefTag:
@@ -23026,8 +23028,6 @@ namespace ts {
2302623028 return checkIndexedAccessType(<IndexedAccessTypeNode>node);
2302723029 case SyntaxKind.MappedType:
2302823030 return checkMappedType(<MappedTypeNode>node);
23029- case SyntaxKind.ESSymbolType:
23030- return checkSymbolType(<ESSymbolTypeNode>node);
2303123031 case SyntaxKind.FunctionDeclaration:
2303223032 return checkFunctionDeclaration(<FunctionDeclaration>node);
2303323033 case SyntaxKind.Block:
@@ -25341,54 +25341,60 @@ namespace ts {
2534125341 }
2534225342 }
2534325343
25344- function checkGrammarESSymbolTypeNode (node: ESSymbolTypeNode ) {
25345- let parent = node.parent;
25346- while (parent. kind === SyntaxKind.ParenthesizedType ) {
25347- parent = parent.parent ;
25348- }
25344+ function checkGrammarTypeOperatorNode (node: TypeOperatorNode ) {
25345+ if (node.operator === SyntaxKind.UniqueKeyword) {
25346+ if (node.type. kind !== SyntaxKind.SymbolKeyword ) {
25347+ return grammarErrorOnNode(node.type, Diagnostics._0_expected, tokenToString(SyntaxKind.SymbolKeyword)) ;
25348+ }
2534925349
25350- switch (parent.kind) {
25351- case SyntaxKind.VariableDeclaration:
25352- const decl = parent as VariableDeclaration;
25353- if (decl.name.kind !== SyntaxKind.Identifier) {
25354- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
25355- }
25356- if (!isVariableDeclarationInVariableStatement(decl)) {
25357- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
25358- }
25359- if (!(decl.parent.flags & NodeFlags.Const)) {
25360- return grammarErrorOnNode((<VariableDeclaration>parent).name, Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
25361- }
25362- break;
25350+ let parent = node.parent;
25351+ while (parent.kind === SyntaxKind.ParenthesizedType) {
25352+ parent = parent.parent;
25353+ }
2536325354
25364- case SyntaxKind.PropertyDeclaration:
25365- if (!hasModifier(parent, ModifierFlags.Static) ||
25366- !hasModifier(parent, ModifierFlags.Readonly)) {
25367- return grammarErrorOnNode((<PropertyDeclaration>parent).name, Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
25368- }
25369- break;
25355+ switch (parent.kind) {
25356+ case SyntaxKind.VariableDeclaration:
25357+ const decl = parent as VariableDeclaration;
25358+ if (decl.name.kind !== SyntaxKind.Identifier) {
25359+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
25360+ }
25361+ if (!isVariableDeclarationInVariableStatement(decl)) {
25362+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
25363+ }
25364+ if (!(decl.parent.flags & NodeFlags.Const)) {
25365+ return grammarErrorOnNode((<VariableDeclaration>parent).name, Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
25366+ }
25367+ break;
2537025368
25371- case SyntaxKind.PropertySignature:
25372- if (!hasModifier(parent, ModifierFlags.Readonly)) {
25373- return grammarErrorOnNode((<PropertySignature>parent).name, Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
25374- }
25375- break;
25369+ case SyntaxKind.PropertyDeclaration:
25370+ if (!hasModifier(parent, ModifierFlags.Static) ||
25371+ !hasModifier(parent, ModifierFlags.Readonly)) {
25372+ return grammarErrorOnNode((<PropertyDeclaration>parent).name, Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
25373+ }
25374+ break;
2537625375
25377- // report specific errors for cases where a `symbol()` type is disallowed even when it is in a `const` or `readonly` declaration.
25378- case SyntaxKind.UnionType:
25379- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_in_a_union_type);
25380- case SyntaxKind.IntersectionType:
25381- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_in_an_intersection_type);
25382- case SyntaxKind.ArrayType:
25383- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_in_an_array_type);
25384- case SyntaxKind.TupleType:
25385- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_in_a_tuple_type);
25386- case SyntaxKind.MappedType:
25387- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_in_a_mapped_type);
25376+ case SyntaxKind.PropertySignature:
25377+ if (!hasModifier(parent, ModifierFlags.Readonly)) {
25378+ return grammarErrorOnNode((<PropertySignature>parent).name, Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
25379+ }
25380+ break;
2538825381
25389- // report a general error for any other invalid use site.
25390- default:
25391- return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_not_allowed_here);
25382+ // report specific errors for cases where a `unique symbol` type is disallowed even when it is in a `const` or `readonly` declaration.
25383+ case SyntaxKind.UnionType:
25384+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_union_type);
25385+ case SyntaxKind.IntersectionType:
25386+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_an_intersection_type);
25387+ case SyntaxKind.ArrayType:
25388+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_an_array_type);
25389+ case SyntaxKind.TupleType:
25390+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_tuple_type);
25391+ case SyntaxKind.MappedType:
25392+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_mapped_type);
25393+
25394+ // report a general error for any other invalid use site.
25395+ default:
25396+ return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here);
25397+ }
2539225398 }
2539325399 }
2539425400
0 commit comments