@@ -13097,6 +13097,11 @@ namespace ts {
13097
13097
isUnitType(type);
13098
13098
}
13099
13099
13100
+ function isStringOrNumericLiteralType(type: Type): boolean {
13101
+ return type.flags & TypeFlags.Union ? every((<UnionType>type).types, t => !!(t.flags & TypeFlags.StringOrNumberLiteral && !(t.flags & (TypeFlags.EnumLike | TypeFlags.Intrinsic)))) :
13102
+ !!(type.flags & TypeFlags.StringOrNumberLiteral) && !(type.flags & (TypeFlags.EnumLike | TypeFlags.Intrinsic))
13103
+ }
13104
+
13100
13105
function getBaseTypeOfLiteralType(type: Type): Type {
13101
13106
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
13102
13107
type.flags & TypeFlags.StringLiteral ? stringType :
@@ -21584,17 +21589,7 @@ namespace ts {
21584
21589
}
21585
21590
21586
21591
function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
21587
- let operandType: Type;
21588
- const symbol = isEntityNameExpression(node.operand) ? isPropertyAccessEntityNameExpression(node.operand) ?
21589
- getSymbolAtLocation((<PropertyAccessExpression>node.operand).name) : getResolvedSymbol(node.operand as Identifier) : undefined;
21590
- if (symbol && !(getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const)) {
21591
- operandType = getTypeOfSymbol(symbol);
21592
- if (isLiteralType(operandType) && !(operandType.flags & (TypeFlags.EnumLike | TypeFlags.BooleanLike | TypeFlags.Undefined))) {
21593
- error(node.operand, Diagnostics.The_literal_type_0_cannot_be_modified, typeToString(operandType));
21594
- }
21595
- }
21596
- operandType = checkExpression(node.operand);
21597
-
21592
+ const operandType = checkExpression(node.operand);
21598
21593
if (operandType === silentNeverType) {
21599
21594
return silentNeverType;
21600
21595
}
@@ -21619,6 +21614,21 @@ namespace ts {
21619
21614
return numberType;
21620
21615
}
21621
21616
21617
+ function checkUnaryExpression(node: PrefixUnaryExpression | PostfixUnaryExpression): Type {
21618
+ const symbol = isEntityNameExpression(node.operand) ? isPropertyAccessEntityNameExpression(node.operand) ?
21619
+ getSymbolAtLocation((<PropertyAccessExpression>node.operand).name) : getResolvedSymbol(node.operand as Identifier) : undefined;
21620
+ if (symbol && isUnaryAssignmentOperator(node.operator) && !(getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const)) {
21621
+ const operandType = getTypeOfSymbol(symbol);
21622
+ if (isStringOrNumericLiteralType(operandType)) {
21623
+ error(node.operand, Diagnostics.The_literal_type_0_cannot_be_modified, typeToString(operandType));
21624
+ }
21625
+ }
21626
+ if (node.kind == SyntaxKind.PrefixUnaryExpression) {
21627
+ return checkPrefixUnaryExpression(node)
21628
+ }
21629
+ return checkPostfixUnaryExpression(node)
21630
+ }
21631
+
21622
21632
// Return true if type might be of the given kind. A union or intersection type might be of a given
21623
21633
// kind if at least one constituent type is of the given kind.
21624
21634
function maybeTypeOfKind(type: Type, kind: TypeFlags): boolean {
@@ -21967,7 +21977,7 @@ namespace ts {
21967
21977
getSymbolAtLocation((<PropertyAccessExpression>left).name) : getResolvedSymbol(left as Identifier) : undefined;
21968
21978
if (symbol && isCompoundAssignmentOperator(operator) && !(getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const)) {
21969
21979
leftType = getTypeOfSymbol(getResolvedSymbol(left as Identifier));
21970
- if (isLiteralType (leftType) && !(leftType.flags & (TypeFlags.EnumLike | TypeFlags.BooleanLike | TypeFlags.Undefined) )) {
21980
+ if (isStringOrNumericLiteralType (leftType)) {
21971
21981
error(left, Diagnostics.The_literal_type_0_cannot_be_modified, typeToString(leftType));
21972
21982
}
21973
21983
}
@@ -22658,9 +22668,8 @@ namespace ts {
22658
22668
case SyntaxKind.AwaitExpression:
22659
22669
return checkAwaitExpression(<AwaitExpression>node);
22660
22670
case SyntaxKind.PrefixUnaryExpression:
22661
- return checkPrefixUnaryExpression(<PrefixUnaryExpression>node);
22662
22671
case SyntaxKind.PostfixUnaryExpression:
22663
- return checkPostfixUnaryExpression(< PostfixUnaryExpression>node);
22672
+ return checkUnaryExpression(<PrefixUnaryExpression | PostfixUnaryExpression>node);
22664
22673
case SyntaxKind.BinaryExpression:
22665
22674
return checkBinaryExpression(<BinaryExpression>node, checkMode);
22666
22675
case SyntaxKind.ConditionalExpression:
0 commit comments