Skip to content

Commit b5a7b03

Browse files
committed
Address PR feedback
1 parent ccd98af commit b5a7b03

7 files changed

Lines changed: 174 additions & 190 deletions

File tree

src/compiler/checker.ts

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7924,14 +7924,7 @@ namespace ts {
79247924
links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
79257925
break;
79267926
case SyntaxKind.UniqueKeyword:
7927-
if (node.type.kind === SyntaxKind.SymbolKeyword) {
7928-
const parent = skipParentheses(node).parent;
7929-
const symbol = getSymbolOfNode(parent);
7930-
links.resolvedType = symbol ? getUniqueESSymbolTypeForSymbol(symbol) : esSymbolType;
7931-
}
7932-
else {
7933-
links.resolvedType = unknownType;
7934-
}
7927+
links.resolvedType = getUniqueType(<UniqueTypeOperatorNode>node);
79357928
break;
79367929
}
79377930
}
@@ -8299,37 +8292,35 @@ namespace ts {
82998292
return links.resolvedType;
83008293
}
83018294

8295+
function nodeCanHaveUniqueESSymbolType(node: Node) {
8296+
return isVariableDeclaration(node) ? isConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) :
8297+
isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) :
8298+
isPropertySignature(node) ? hasReadonlyModifier(node) :
8299+
false;
8300+
}
8301+
83028302
function createUniqueESSymbolType(symbol: Symbol) {
83038303
const type = <UniqueESSymbolType>createType(TypeFlags.UniqueESSymbol);
83048304
type.symbol = symbol;
83058305
return type;
83068306
}
83078307

8308-
function isReferenceToValidDeclarationForUniqueESSymbol(symbol: Symbol) {
8309-
if (symbol.valueDeclaration) {
8310-
switch (symbol.valueDeclaration.kind) {
8311-
case SyntaxKind.VariableDeclaration:
8312-
return getNameOfDeclaration(symbol.valueDeclaration).kind === SyntaxKind.Identifier
8313-
&& isVariableDeclarationInVariableStatement(<VariableDeclaration>symbol.valueDeclaration)
8314-
&& !!(symbol.valueDeclaration.parent.flags & NodeFlags.Const);
8315-
case SyntaxKind.PropertySignature:
8316-
return hasModifier(symbol.valueDeclaration, ModifierFlags.Readonly);
8317-
case SyntaxKind.PropertyDeclaration:
8318-
return hasModifier(symbol.valueDeclaration, ModifierFlags.Readonly)
8319-
&& hasModifier(symbol.valueDeclaration, ModifierFlags.Static);
8320-
}
8321-
}
8322-
return false;
8323-
}
8324-
8325-
function getUniqueESSymbolTypeForSymbol(symbol: Symbol) {
8326-
if (isReferenceToValidDeclarationForUniqueESSymbol(symbol)) {
8308+
function getUniqueESSymbolTypeForNode(node: Node) {
8309+
const parent = walkUpParentheses(node);
8310+
if (nodeCanHaveUniqueESSymbolType(parent)) {
8311+
const symbol = getSymbolOfNode(parent);
83278312
const links = getSymbolLinks(symbol);
83288313
return links.type || (links.type = createUniqueESSymbolType(symbol));
83298314
}
83308315
return esSymbolType;
83318316
}
83328317

8318+
function getUniqueType(node: UniqueTypeOperatorNode) {
8319+
return node.type.kind === SyntaxKind.SymbolKeyword
8320+
? getUniqueESSymbolTypeForNode(node.parent)
8321+
: unknownType;
8322+
}
8323+
83338324
function getTypeFromJSDocVariadicType(node: JSDocVariadicType): Type {
83348325
const links = getNodeLinks(node);
83358326
if (!links.resolvedType) {
@@ -17180,9 +17171,7 @@ namespace ts {
1718017171
// Treat any call to the global 'Symbol' function that is part of a const variable or readonly property
1718117172
// as a fresh unique symbol literal type.
1718217173
if (returnType.flags & TypeFlags.ESSymbolLike && isSymbolOrSymbolForCall(node)) {
17183-
const parent = skipParentheses(node).parent;
17184-
const symbol = getSymbolOfNode(parent);
17185-
if (symbol) return getUniqueESSymbolTypeForSymbol(symbol);
17174+
return getUniqueESSymbolTypeForNode(node.parent);
1718617175
}
1718717176
return returnType;
1718817177
}
@@ -25542,19 +25531,6 @@ namespace ts {
2554225531
}
2554325532
break;
2554425533

25545-
// report specific errors for cases where a `unique symbol` type is disallowed even when it is in a `const` or `readonly` declaration.
25546-
case SyntaxKind.UnionType:
25547-
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_union_type);
25548-
case SyntaxKind.IntersectionType:
25549-
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_an_intersection_type);
25550-
case SyntaxKind.ArrayType:
25551-
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_an_array_type);
25552-
case SyntaxKind.TupleType:
25553-
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_tuple_type);
25554-
case SyntaxKind.MappedType:
25555-
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_in_a_mapped_type);
25556-
25557-
// report a general error for any other invalid use site.
2555825534
default:
2555925535
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here);
2556025536
}

src/compiler/diagnosticMessages.json

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -911,49 +911,29 @@
911911
"category": "Error",
912912
"code": 1329
913913
},
914-
"'unique symbol' types are not allowed in a union type.": {
915-
"category": "Error",
916-
"code": 1330
917-
},
918-
"'unique symbol' types are not allowed in an intersection type.": {
919-
"category": "Error",
920-
"code": 1331
921-
},
922-
"'unique symbol' types are not allowed in an array type.": {
923-
"category": "Error",
924-
"code": 1332
925-
},
926-
"'unique symbol' types are not allowed in a tuple type.": {
927-
"category": "Error",
928-
"code": 1333
929-
},
930-
"'unique symbol' types are not allowed in a mapped type.": {
931-
"category": "Error",
932-
"code": 1334
933-
},
934914
"A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.": {
935915
"category": "Error",
936-
"code": 1335
916+
"code": 1330
937917
},
938918
"A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.": {
939919
"category": "Error",
940-
"code": 1336
920+
"code": 1331
941921
},
942922
"A variable whose type is a 'unique symbol' type must be 'const'.": {
943923
"category": "Error",
944-
"code": 1337
924+
"code": 1332
945925
},
946926
"'unique symbol' types may not be used on a variable declaration with a binding name.": {
947927
"category": "Error",
948-
"code": 1338
928+
"code": 1333
949929
},
950930
"'unique symbol' types are only allowed on variables in a variable statement.": {
951931
"category": "Error",
952-
"code": 1339
932+
"code": 1334
953933
},
954934
"'unique symbol' types are not allowed here.": {
955935
"category": "Error",
956-
"code": 1340
936+
"code": 1335
957937
},
958938

959939
"Duplicate identifier '{0}'.": {

src/compiler/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,11 @@ namespace ts {
10461046
type: TypeNode;
10471047
}
10481048

1049+
/* @internal */
1050+
export interface UniqueTypeOperatorNode extends TypeOperatorNode {
1051+
operator: SyntaxKind.UniqueKeyword;
1052+
}
1053+
10491054
export interface IndexedAccessTypeNode extends TypeNode {
10501055
kind: SyntaxKind.IndexedAccessType;
10511056
objectType: TypeNode;

src/compiler/utilities.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1695,12 +1695,27 @@ namespace ts {
16951695
return getAssignmentTargetKind(node) !== AssignmentKind.None;
16961696
}
16971697

1698+
export function walkUpParentheses(node: Node) {
1699+
while (node && (node.kind === SyntaxKind.ParenthesizedType ||
1700+
node.kind === SyntaxKind.ParenthesizedExpression)) {
1701+
node = node.parent;
1702+
}
1703+
return node;
1704+
}
1705+
1706+
export function walkUpParenthesizedExpressions(node: Node) {
1707+
while (node && node.kind === SyntaxKind.ParenthesizedExpression) {
1708+
node = node.parent;
1709+
}
1710+
return node;
1711+
}
1712+
16981713
// a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
16991714
export function isDeleteTarget(node: Node): boolean {
17001715
if (node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) {
17011716
return false;
17021717
}
1703-
node = node.parent;
1718+
node = walkUpParenthesizedExpressions(node.parent);
17041719
while (node && node.kind === SyntaxKind.ParenthesizedExpression) {
17051720
node = node.parent;
17061721
}
@@ -3009,6 +3024,10 @@ namespace ts {
30093024
return hasModifier(node, ModifierFlags.Static);
30103025
}
30113026

3027+
export function hasReadonlyModifier(node: Node): boolean {
3028+
return hasModifier(node, ModifierFlags.Readonly);
3029+
}
3030+
30123031
export function getSelectedModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags {
30133032
return getModifierFlags(node) & flags;
30143033
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,7 @@ declare namespace ts {
19891989
IndexedAccess = 1048576,
19901990
NonPrimitive = 33554432,
19911991
MarkerType = 134217728,
1992-
Literal = 1248,
1992+
Literal = 224,
19931993
Unit = 13536,
19941994
StringOrNumberLiteral = 96,
19951995
PossiblyFalsy = 14574,
@@ -2004,6 +2004,8 @@ declare namespace ts {
20042004
TypeVariable = 1081344,
20052005
Narrowable = 35620607,
20062006
NotUnionOrUnit = 33620481,
2007+
WidenableLiteral = 480,
2008+
WidenableLiteralLike = 1504,
20072009
}
20082010
type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
20092011
interface Type {

tests/baselines/reference/api/typescript.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,7 @@ declare namespace ts {
19891989
IndexedAccess = 1048576,
19901990
NonPrimitive = 33554432,
19911991
MarkerType = 134217728,
1992-
Literal = 1248,
1992+
Literal = 224,
19931993
Unit = 13536,
19941994
StringOrNumberLiteral = 96,
19951995
PossiblyFalsy = 14574,
@@ -2004,6 +2004,8 @@ declare namespace ts {
20042004
TypeVariable = 1081344,
20052005
Narrowable = 35620607,
20062006
NotUnionOrUnit = 33620481,
2007+
WidenableLiteral = 480,
2008+
WidenableLiteralLike = 1504,
20072009
}
20082010
type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
20092011
interface Type {

0 commit comments

Comments
 (0)