@@ -193,8 +193,8 @@ namespace ts {
193
193
const intersectionTypes: Map<IntersectionType> = {};
194
194
const stringLiteralTypes: Map<StringLiteralType> = {};
195
195
const numericLiteralTypes: Map<NumericLiteralType> = {};
196
- const NaNLiteralType = getNumericLiteralTypeForText (NaN.toString() );
197
- const InfinityLiteralType = getNumericLiteralTypeForText (Infinity.toString() );
196
+ const NaNLiteralType = getNumericLiteralTypeForNumber (NaN);
197
+ const InfinityLiteralType = getNumericLiteralTypeForNumber (Infinity);
198
198
199
199
const resolutionTargets: TypeSystemEntity[] = [];
200
200
const resolutionResults: boolean[] = [];
@@ -5110,9 +5110,10 @@ namespace ts {
5110
5110
function getNumericLiteralTypeForText(text: string): NumericLiteralType {
5111
5111
// Use +(string) rather than Number(string) to be consistient with what we use in the parser
5112
5112
const num = +(text);
5113
- if (typeof num !== "number") {
5114
- return NaNLiteralType;
5115
- }
5113
+ return getNumericLiteralTypeForNumber(num, text);
5114
+ }
5115
+
5116
+ function getNumericLiteralTypeForNumber(num: number, text: string = num.toString()): NumericLiteralType {
5116
5117
if (hasProperty(numericLiteralTypes, text)) {
5117
5118
return numericLiteralTypes[text];
5118
5119
}
@@ -5134,7 +5135,7 @@ namespace ts {
5134
5135
function getTypeFromNumericLiteralTypeNode(node: NumericLiteralTypeNode): Type {
5135
5136
const links = getNodeLinks(node);
5136
5137
if (!links.resolvedType) {
5137
- links.resolvedType = getNumericLiteralTypeForText( node.text);
5138
+ links.resolvedType = getNumericLiteralTypeForNumber(node.number, node.text);
5138
5139
}
5139
5140
return links.resolvedType;
5140
5141
}
@@ -11877,13 +11878,13 @@ namespace ts {
11877
11878
if (operandType.flags & TypeFlags.NumericLiteral) {
11878
11879
const litType = operandType as NumericLiteralType;
11879
11880
const newNumber = -litType.number;
11880
- return getNumericLiteralTypeForText (newNumber.toString() );
11881
+ return getNumericLiteralTypeForNumber (newNumber);
11881
11882
}
11882
11883
case SyntaxKind.TildeToken:
11883
11884
if (operandType.flags & TypeFlags.NumericLiteral) {
11884
11885
const litType = operandType as NumericLiteralType;
11885
11886
const newNumber = ~litType.number;
11886
- return getNumericLiteralTypeForText (newNumber.toString() );
11887
+ return getNumericLiteralTypeForNumber (newNumber);
11887
11888
}
11888
11889
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
11889
11890
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
@@ -11895,14 +11896,14 @@ namespace ts {
11895
11896
if (operandType.flags & TypeFlags.NumericLiteral) {
11896
11897
const litType = operandType as NumericLiteralType;
11897
11898
const newNumber = litType.number + 1;
11898
- return getNumericLiteralTypeForText (newNumber.toString() );
11899
+ return getNumericLiteralTypeForNumber (newNumber);
11899
11900
}
11900
11901
// Intentional fallthrough
11901
11902
case SyntaxKind.MinusMinusToken:
11902
11903
if (operandType.flags & TypeFlags.NumericLiteral) {
11903
11904
const litType = operandType as NumericLiteralType;
11904
11905
const newNumber = litType.number - 1;
11905
- return getNumericLiteralTypeForText (newNumber.toString() );
11906
+ return getNumericLiteralTypeForNumber (newNumber);
11906
11907
}
11907
11908
const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType),
11908
11909
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
@@ -12161,49 +12162,49 @@ namespace ts {
12161
12162
case SyntaxKind.AsteriskEqualsToken:
12162
12163
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12163
12164
const newNumber = (leftType as NumericLiteralType).number * (rightType as NumericLiteralType).number;
12164
- return getNumericLiteralTypeForText (newNumber.toString() );
12165
+ return getNumericLiteralTypeForNumber (newNumber);
12165
12166
}
12166
12167
case SyntaxKind.AsteriskAsteriskToken:
12167
12168
case SyntaxKind.AsteriskAsteriskEqualsToken:
12168
12169
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12169
12170
const newNumber = (leftType as NumericLiteralType).number ** (rightType as NumericLiteralType).number;
12170
- return getNumericLiteralTypeForText (newNumber.toString() );
12171
+ return getNumericLiteralTypeForNumber (newNumber);
12171
12172
}
12172
12173
case SyntaxKind.SlashToken:
12173
12174
case SyntaxKind.SlashEqualsToken:
12174
12175
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12175
12176
const newNumber = (leftType as NumericLiteralType).number / (rightType as NumericLiteralType).number;
12176
- return getNumericLiteralTypeForText (newNumber.toString() );
12177
+ return getNumericLiteralTypeForNumber (newNumber);
12177
12178
}
12178
12179
case SyntaxKind.PercentToken:
12179
12180
case SyntaxKind.PercentEqualsToken:
12180
12181
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12181
12182
const newNumber = (leftType as NumericLiteralType).number % (rightType as NumericLiteralType).number;
12182
- return getNumericLiteralTypeForText (newNumber.toString() );
12183
+ return getNumericLiteralTypeForNumber (newNumber);
12183
12184
}
12184
12185
case SyntaxKind.MinusToken:
12185
12186
case SyntaxKind.MinusEqualsToken:
12186
12187
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12187
12188
const newNumber = (leftType as NumericLiteralType).number - (rightType as NumericLiteralType).number;
12188
- return getNumericLiteralTypeForText (newNumber.toString() );
12189
+ return getNumericLiteralTypeForNumber (newNumber);
12189
12190
}
12190
12191
case SyntaxKind.BarToken:
12191
12192
case SyntaxKind.BarEqualsToken:
12192
12193
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12193
12194
const newNumber = (leftType as NumericLiteralType).number | (rightType as NumericLiteralType).number;
12194
- return getNumericLiteralTypeForText (newNumber.toString() );
12195
+ return getNumericLiteralTypeForNumber (newNumber);
12195
12196
}
12196
12197
case SyntaxKind.CaretToken:
12197
12198
case SyntaxKind.CaretEqualsToken:
12198
12199
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12199
12200
const newNumber = (leftType as NumericLiteralType).number ^ (rightType as NumericLiteralType).number;
12200
- return getNumericLiteralTypeForText (newNumber.toString() );
12201
+ return getNumericLiteralTypeForNumber (newNumber);
12201
12202
}
12202
12203
case SyntaxKind.AmpersandToken:
12203
12204
case SyntaxKind.AmpersandEqualsToken:
12204
12205
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12205
12206
const newNumber = (leftType as NumericLiteralType).number & (rightType as NumericLiteralType).number;
12206
- return getNumericLiteralTypeForText (newNumber.toString() );
12207
+ return getNumericLiteralTypeForNumber (newNumber);
12207
12208
}
12208
12209
case SyntaxKind.LessThanLessThanToken:
12209
12210
case SyntaxKind.LessThanLessThanEqualsToken:
@@ -12246,7 +12247,7 @@ namespace ts {
12246
12247
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
12247
12248
// TODO (weswig): add case for when 1 side is a string literal type and the other is a numeric literal, then cast as appropriate
12248
12249
const newNumber = (leftType as NumericLiteralType).number + (rightType as NumericLiteralType).number;
12249
- return getNumericLiteralTypeForText (newNumber.toString() );
12250
+ return getNumericLiteralTypeForNumber (newNumber);
12250
12251
}
12251
12252
// TypeScript 1.0 spec (April 2014): 4.19.2
12252
12253
// The binary + operator requires both operands to be of the Number primitive type or an enum type,
0 commit comments