@@ -183,8 +183,8 @@ namespace ts {
183
183
const intersectionTypes: Map<IntersectionType> = {};
184
184
const stringLiteralTypes: Map<StringLiteralType> = {};
185
185
const numericLiteralTypes: Map<NumericLiteralType> = {};
186
- const NaNLiteralType = getNumericLiteralTypeForText (NaN.toString() );
187
- const InfinityLiteralType = getNumericLiteralTypeForText (Infinity.toString() );
186
+ const NaNLiteralType = getNumericLiteralTypeForNumber (NaN);
187
+ const InfinityLiteralType = getNumericLiteralTypeForNumber (Infinity);
188
188
189
189
const resolutionTargets: TypeSystemEntity[] = [];
190
190
const resolutionResults: boolean[] = [];
@@ -4944,9 +4944,10 @@ namespace ts {
4944
4944
function getNumericLiteralTypeForText(text: string): NumericLiteralType {
4945
4945
// Use +(string) rather than Number(string) to be consistient with what we use in the parser
4946
4946
const num = +(text);
4947
- if (typeof num !== "number") {
4948
- return NaNLiteralType;
4949
- }
4947
+ return getNumericLiteralTypeForNumber(num, text);
4948
+ }
4949
+
4950
+ function getNumericLiteralTypeForNumber(num: number, text: string = num.toString()): NumericLiteralType {
4950
4951
if (hasProperty(numericLiteralTypes, text)) {
4951
4952
return numericLiteralTypes[text];
4952
4953
}
@@ -4968,7 +4969,7 @@ namespace ts {
4968
4969
function getTypeFromNumericLiteralTypeNode(node: NumericLiteralTypeNode): Type {
4969
4970
const links = getNodeLinks(node);
4970
4971
if (!links.resolvedType) {
4971
- links.resolvedType = getNumericLiteralTypeForText( node.text);
4972
+ links.resolvedType = getNumericLiteralTypeForNumber(node.number, node.text);
4972
4973
}
4973
4974
return links.resolvedType;
4974
4975
}
@@ -11206,13 +11207,13 @@ namespace ts {
11206
11207
if (operandType.flags & TypeFlags.NumericLiteral) {
11207
11208
const litType = operandType as NumericLiteralType;
11208
11209
const newNumber = -litType.number;
11209
- return getNumericLiteralTypeForText (newNumber.toString() );
11210
+ return getNumericLiteralTypeForNumber (newNumber);
11210
11211
}
11211
11212
case SyntaxKind.TildeToken:
11212
11213
if (operandType.flags & TypeFlags.NumericLiteral) {
11213
11214
const litType = operandType as NumericLiteralType;
11214
11215
const newNumber = ~litType.number;
11215
- return getNumericLiteralTypeForText (newNumber.toString() );
11216
+ return getNumericLiteralTypeForNumber (newNumber);
11216
11217
}
11217
11218
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
11218
11219
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
@@ -11224,13 +11225,13 @@ namespace ts {
11224
11225
if (operandType.flags & TypeFlags.NumericLiteral) {
11225
11226
const litType = operandType as NumericLiteralType;
11226
11227
const newNumber = litType.number + 1;
11227
- return getNumericLiteralTypeForText (newNumber.toString() );
11228
+ return getNumericLiteralTypeForNumber (newNumber);
11228
11229
}
11229
11230
case SyntaxKind.MinusMinusToken:
11230
11231
if (operandType.flags & TypeFlags.NumericLiteral) {
11231
11232
const litType = operandType as NumericLiteralType;
11232
11233
const newNumber = litType.number - 1;
11233
- return getNumericLiteralTypeForText (newNumber.toString() );
11234
+ return getNumericLiteralTypeForNumber (newNumber);
11234
11235
}
11235
11236
const ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
11236
11237
if (ok) {
@@ -11476,49 +11477,49 @@ namespace ts {
11476
11477
case SyntaxKind.AsteriskEqualsToken:
11477
11478
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11478
11479
const newNumber = (leftType as NumericLiteralType).number * (rightType as NumericLiteralType).number;
11479
- return getNumericLiteralTypeForText (newNumber.toString() );
11480
+ return getNumericLiteralTypeForNumber (newNumber);
11480
11481
}
11481
11482
case SyntaxKind.AsteriskAsteriskToken:
11482
11483
case SyntaxKind.AsteriskAsteriskEqualsToken:
11483
11484
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11484
11485
const newNumber = (leftType as NumericLiteralType).number ** (rightType as NumericLiteralType).number;
11485
- return getNumericLiteralTypeForText (newNumber.toString() );
11486
+ return getNumericLiteralTypeForNumber (newNumber);
11486
11487
}
11487
11488
case SyntaxKind.SlashToken:
11488
11489
case SyntaxKind.SlashEqualsToken:
11489
11490
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11490
11491
const newNumber = (leftType as NumericLiteralType).number / (rightType as NumericLiteralType).number;
11491
- return getNumericLiteralTypeForText (newNumber.toString() );
11492
+ return getNumericLiteralTypeForNumber (newNumber);
11492
11493
}
11493
11494
case SyntaxKind.PercentToken:
11494
11495
case SyntaxKind.PercentEqualsToken:
11495
11496
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11496
11497
const newNumber = (leftType as NumericLiteralType).number % (rightType as NumericLiteralType).number;
11497
- return getNumericLiteralTypeForText (newNumber.toString() );
11498
+ return getNumericLiteralTypeForNumber (newNumber);
11498
11499
}
11499
11500
case SyntaxKind.MinusToken:
11500
11501
case SyntaxKind.MinusEqualsToken:
11501
11502
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11502
11503
const newNumber = (leftType as NumericLiteralType).number - (rightType as NumericLiteralType).number;
11503
- return getNumericLiteralTypeForText (newNumber.toString() );
11504
+ return getNumericLiteralTypeForNumber (newNumber);
11504
11505
}
11505
11506
case SyntaxKind.BarToken:
11506
11507
case SyntaxKind.BarEqualsToken:
11507
11508
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11508
11509
const newNumber = (leftType as NumericLiteralType).number | (rightType as NumericLiteralType).number;
11509
- return getNumericLiteralTypeForText (newNumber.toString() );
11510
+ return getNumericLiteralTypeForNumber (newNumber);
11510
11511
}
11511
11512
case SyntaxKind.CaretToken:
11512
11513
case SyntaxKind.CaretEqualsToken:
11513
11514
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11514
11515
const newNumber = (leftType as NumericLiteralType).number ^ (rightType as NumericLiteralType).number;
11515
- return getNumericLiteralTypeForText (newNumber.toString() );
11516
+ return getNumericLiteralTypeForNumber (newNumber);
11516
11517
}
11517
11518
case SyntaxKind.AmpersandToken:
11518
11519
case SyntaxKind.AmpersandEqualsToken:
11519
11520
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11520
11521
const newNumber = (leftType as NumericLiteralType).number & (rightType as NumericLiteralType).number;
11521
- return getNumericLiteralTypeForText (newNumber.toString() );
11522
+ return getNumericLiteralTypeForNumber (newNumber);
11522
11523
}
11523
11524
case SyntaxKind.LessThanLessThanToken:
11524
11525
case SyntaxKind.LessThanLessThanEqualsToken:
@@ -11558,7 +11559,7 @@ namespace ts {
11558
11559
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
11559
11560
// TODO (weswig): add case for when 1 side is a string literal type and the other is a numeric literal, then cast as appropriate
11560
11561
const newNumber = (leftType as NumericLiteralType).number + (rightType as NumericLiteralType).number;
11561
- return getNumericLiteralTypeForText (newNumber.toString() );
11562
+ return getNumericLiteralTypeForNumber (newNumber);
11562
11563
}
11563
11564
// TypeScript 1.0 spec (April 2014): 4.19.2
11564
11565
// The binary + operator requires both operands to be of the Number primitive type or an enum type,
0 commit comments