|
|
|
|
@@ -403,6 +403,7 @@ namespace ts {
|
|
|
|
|
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsWideningType, "null");
|
|
|
|
|
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
|
|
|
|
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
|
|
|
|
const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint");
|
|
|
|
|
const falseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false") as FreshableIntrinsicType;
|
|
|
|
|
const regularFalseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false") as FreshableIntrinsicType;
|
|
|
|
|
const trueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true") as FreshableIntrinsicType;
|
|
|
|
|
@@ -427,6 +428,7 @@ namespace ts {
|
|
|
|
|
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
|
|
|
|
|
const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
|
|
|
|
|
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
|
|
|
|
|
const numberOrBigIntType = getUnionType([numberType, bigintType]);
|
|
|
|
|
|
|
|
|
|
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
|
|
|
|
|
|
|
|
|
@@ -518,6 +520,7 @@ namespace ts {
|
|
|
|
|
let deferredGlobalTemplateStringsArrayType: ObjectType;
|
|
|
|
|
let deferredGlobalImportMetaType: ObjectType;
|
|
|
|
|
let deferredGlobalExtractSymbol: Symbol;
|
|
|
|
|
let deferredGlobalBigIntType: ObjectType;
|
|
|
|
|
|
|
|
|
|
const allPotentiallyUnusedIdentifiers = createMap<PotentiallyUnusedIdentifier[]>(); // key is file name
|
|
|
|
|
|
|
|
|
|
@@ -528,6 +531,7 @@ namespace ts {
|
|
|
|
|
|
|
|
|
|
const emptyStringType = getLiteralType("");
|
|
|
|
|
const zeroType = getLiteralType(0);
|
|
|
|
|
const zeroBigIntType = getLiteralType({ negative: false, base10Value: "0" });
|
|
|
|
|
|
|
|
|
|
const resolutionTargets: TypeSystemEntity[] = [];
|
|
|
|
|
const resolutionResults: boolean[] = [];
|
|
|
|
|
@@ -556,31 +560,33 @@ namespace ts {
|
|
|
|
|
None = 0,
|
|
|
|
|
TypeofEQString = 1 << 0, // typeof x === "string"
|
|
|
|
|
TypeofEQNumber = 1 << 1, // typeof x === "number"
|
|
|
|
|
TypeofEQBoolean = 1 << 2, // typeof x === "boolean"
|
|
|
|
|
TypeofEQSymbol = 1 << 3, // typeof x === "symbol"
|
|
|
|
|
TypeofEQObject = 1 << 4, // typeof x === "object"
|
|
|
|
|
TypeofEQFunction = 1 << 5, // typeof x === "function"
|
|
|
|
|
TypeofEQHostObject = 1 << 6, // typeof x === "xxx"
|
|
|
|
|
TypeofNEString = 1 << 7, // typeof x !== "string"
|
|
|
|
|
TypeofNENumber = 1 << 8, // typeof x !== "number"
|
|
|
|
|
TypeofNEBoolean = 1 << 9, // typeof x !== "boolean"
|
|
|
|
|
TypeofNESymbol = 1 << 10, // typeof x !== "symbol"
|
|
|
|
|
TypeofNEObject = 1 << 11, // typeof x !== "object"
|
|
|
|
|
TypeofNEFunction = 1 << 12, // typeof x !== "function"
|
|
|
|
|
TypeofNEHostObject = 1 << 13, // typeof x !== "xxx"
|
|
|
|
|
EQUndefined = 1 << 14, // x === undefined
|
|
|
|
|
EQNull = 1 << 15, // x === null
|
|
|
|
|
EQUndefinedOrNull = 1 << 16, // x === undefined / x === null
|
|
|
|
|
NEUndefined = 1 << 17, // x !== undefined
|
|
|
|
|
NENull = 1 << 18, // x !== null
|
|
|
|
|
NEUndefinedOrNull = 1 << 19, // x != undefined / x != null
|
|
|
|
|
Truthy = 1 << 20, // x
|
|
|
|
|
Falsy = 1 << 21, // !x
|
|
|
|
|
All = (1 << 22) - 1,
|
|
|
|
|
TypeofEQBigInt = 1 << 2, // typeof x === "bigint"
|
|
|
|
|
TypeofEQBoolean = 1 << 3, // typeof x === "boolean"
|
|
|
|
|
TypeofEQSymbol = 1 << 4, // typeof x === "symbol"
|
|
|
|
|
TypeofEQObject = 1 << 5, // typeof x === "object"
|
|
|
|
|
TypeofEQFunction = 1 << 6, // typeof x === "function"
|
|
|
|
|
TypeofEQHostObject = 1 << 7, // typeof x === "xxx"
|
|
|
|
|
TypeofNEString = 1 << 8, // typeof x !== "string"
|
|
|
|
|
TypeofNENumber = 1 << 9, // typeof x !== "number"
|
|
|
|
|
TypeofNEBigInt = 1 << 10, // typeof x !== "bigint"
|
|
|
|
|
TypeofNEBoolean = 1 << 11, // typeof x !== "boolean"
|
|
|
|
|
TypeofNESymbol = 1 << 12, // typeof x !== "symbol"
|
|
|
|
|
TypeofNEObject = 1 << 13, // typeof x !== "object"
|
|
|
|
|
TypeofNEFunction = 1 << 14, // typeof x !== "function"
|
|
|
|
|
TypeofNEHostObject = 1 << 15, // typeof x !== "xxx"
|
|
|
|
|
EQUndefined = 1 << 16, // x === undefined
|
|
|
|
|
EQNull = 1 << 17, // x === null
|
|
|
|
|
EQUndefinedOrNull = 1 << 18, // x === undefined / x === null
|
|
|
|
|
NEUndefined = 1 << 19, // x !== undefined
|
|
|
|
|
NENull = 1 << 20, // x !== null
|
|
|
|
|
NEUndefinedOrNull = 1 << 21, // x != undefined / x != null
|
|
|
|
|
Truthy = 1 << 22, // x
|
|
|
|
|
Falsy = 1 << 23, // !x
|
|
|
|
|
All = (1 << 24) - 1,
|
|
|
|
|
// The following members encode facts about particular kinds of types for use in the getTypeFacts function.
|
|
|
|
|
// The presence of a particular fact means that the given test is true for some (and possibly all) values
|
|
|
|
|
// of that kind of type.
|
|
|
|
|
BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy,
|
|
|
|
|
StringFacts = BaseStringFacts | Truthy,
|
|
|
|
|
@@ -588,15 +594,23 @@ namespace ts {
|
|
|
|
|
EmptyStringFacts = BaseStringFacts,
|
|
|
|
|
NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy,
|
|
|
|
|
NonEmptyStringFacts = BaseStringFacts | Truthy,
|
|
|
|
|
BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy,
|
|
|
|
|
NumberFacts = BaseNumberFacts | Truthy,
|
|
|
|
|
ZeroStrictFacts = BaseNumberStrictFacts | Falsy,
|
|
|
|
|
ZeroFacts = BaseNumberFacts,
|
|
|
|
|
NonZeroStrictFacts = BaseNumberStrictFacts | Truthy,
|
|
|
|
|
NonZeroFacts = BaseNumberFacts | Truthy,
|
|
|
|
|
BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
ZeroNumberStrictFacts = BaseNumberStrictFacts | Falsy,
|
|
|
|
|
ZeroNumberFacts = BaseNumberFacts,
|
|
|
|
|
NonZeroNumberStrictFacts = BaseNumberStrictFacts | Truthy,
|
|
|
|
|
NonZeroNumberFacts = BaseNumberFacts | Truthy,
|
|
|
|
|
BaseBigIntStrictFacts = TypeofEQBigInt | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseBigIntFacts = BaseBigIntStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
BigIntStrictFacts = BaseBigIntStrictFacts | Truthy | Falsy,
|
|
|
|
|
BigIntFacts = BaseBigIntFacts | Truthy,
|
|
|
|
|
ZeroBigIntStrictFacts = BaseBigIntStrictFacts | Falsy,
|
|
|
|
|
ZeroBigIntFacts = BaseBigIntFacts,
|
|
|
|
|
NonZeroBigIntStrictFacts = BaseBigIntStrictFacts | Truthy,
|
|
|
|
|
NonZeroBigIntFacts = BaseBigIntFacts | Truthy,
|
|
|
|
|
BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull,
|
|
|
|
|
BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy,
|
|
|
|
|
BooleanFacts = BaseBooleanFacts | Truthy,
|
|
|
|
|
@@ -604,14 +618,14 @@ namespace ts {
|
|
|
|
|
FalseFacts = BaseBooleanFacts,
|
|
|
|
|
TrueStrictFacts = BaseBooleanStrictFacts | Truthy,
|
|
|
|
|
TrueFacts = BaseBooleanFacts | Truthy,
|
|
|
|
|
SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
|
|
|
|
FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
|
|
|
|
UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy,
|
|
|
|
|
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
|
|
|
|
|
UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy,
|
|
|
|
|
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
|
|
|
|
|
EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull),
|
|
|
|
|
EmptyObjectFacts = All,
|
|
|
|
|
}
|
|
|
|
|
@@ -619,6 +633,7 @@ namespace ts {
|
|
|
|
|
const typeofEQFacts = createMapFromTemplate({
|
|
|
|
|
string: TypeFacts.TypeofEQString,
|
|
|
|
|
number: TypeFacts.TypeofEQNumber,
|
|
|
|
|
bigint: TypeFacts.TypeofEQBigInt,
|
|
|
|
|
boolean: TypeFacts.TypeofEQBoolean,
|
|
|
|
|
symbol: TypeFacts.TypeofEQSymbol,
|
|
|
|
|
undefined: TypeFacts.EQUndefined,
|
|
|
|
|
@@ -628,6 +643,7 @@ namespace ts {
|
|
|
|
|
const typeofNEFacts = createMapFromTemplate({
|
|
|
|
|
string: TypeFacts.TypeofNEString,
|
|
|
|
|
number: TypeFacts.TypeofNENumber,
|
|
|
|
|
bigint: TypeFacts.TypeofNEBigInt,
|
|
|
|
|
boolean: TypeFacts.TypeofNEBoolean,
|
|
|
|
|
symbol: TypeFacts.TypeofNESymbol,
|
|
|
|
|
undefined: TypeFacts.NEUndefined,
|
|
|
|
|
@@ -637,6 +653,7 @@ namespace ts {
|
|
|
|
|
const typeofTypesByName = createMapFromTemplate<Type>({
|
|
|
|
|
string: stringType,
|
|
|
|
|
number: numberType,
|
|
|
|
|
bigint: bigintType,
|
|
|
|
|
boolean: booleanType,
|
|
|
|
|
symbol: esSymbolType,
|
|
|
|
|
undefined: undefinedType
|
|
|
|
|
@@ -3217,6 +3234,10 @@ namespace ts {
|
|
|
|
|
context.approximateLength += 6;
|
|
|
|
|
return createKeywordTypeNode(SyntaxKind.NumberKeyword);
|
|
|
|
|
}
|
|
|
|
|
if (type.flags & TypeFlags.BigInt) {
|
|
|
|
|
context.approximateLength += 6;
|
|
|
|
|
return createKeywordTypeNode(SyntaxKind.BigIntKeyword);
|
|
|
|
|
}
|
|
|
|
|
if (type.flags & TypeFlags.Boolean) {
|
|
|
|
|
context.approximateLength += 7;
|
|
|
|
|
return createKeywordTypeNode(SyntaxKind.BooleanKeyword);
|
|
|
|
|
@@ -3243,6 +3264,10 @@ namespace ts {
|
|
|
|
|
context.approximateLength += (("" + (<NumberLiteralType>type).value).length);
|
|
|
|
|
return createLiteralTypeNode((createLiteral((<NumberLiteralType>type).value)));
|
|
|
|
|
}
|
|
|
|
|
if (type.flags & TypeFlags.BigIntLiteral) {
|
|
|
|
|
context.approximateLength += (pseudoBigIntToString((<BigIntLiteralType>type).value).length) + 1;
|
|
|
|
|
return createLiteralTypeNode((createLiteral((<BigIntLiteralType>type).value)));
|
|
|
|
|
}
|
|
|
|
|
if (type.flags & TypeFlags.BooleanLiteral) {
|
|
|
|
|
context.approximateLength += (<IntrinsicType>type).intrinsicName.length;
|
|
|
|
|
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
|
|
|
|
|
@@ -6066,6 +6091,7 @@ namespace ts {
|
|
|
|
|
case SyntaxKind.UnknownKeyword:
|
|
|
|
|
case SyntaxKind.StringKeyword:
|
|
|
|
|
case SyntaxKind.NumberKeyword:
|
|
|
|
|
case SyntaxKind.BigIntKeyword:
|
|
|
|
|
case SyntaxKind.BooleanKeyword:
|
|
|
|
|
case SyntaxKind.SymbolKeyword:
|
|
|
|
|
case SyntaxKind.ObjectKeyword:
|
|
|
|
|
@@ -7313,6 +7339,7 @@ namespace ts {
|
|
|
|
|
t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
|
|
|
|
|
t.flags & TypeFlags.StringLike ? globalStringType :
|
|
|
|
|
t.flags & TypeFlags.NumberLike ? globalNumberType :
|
|
|
|
|
t.flags & TypeFlags.BigIntLike ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= ScriptTarget.ESNext) :
|
|
|
|
|
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
|
|
|
|
|
t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) :
|
|
|
|
|
t.flags & TypeFlags.NonPrimitive ? emptyObjectType :
|
|
|
|
|
@@ -8650,6 +8677,10 @@ namespace ts {
|
|
|
|
|
return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)!); // TODO: GH#18217
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getGlobalBigIntType(reportErrors: boolean) {
|
|
|
|
|
return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Instantiates a global type that is generic with some element type, and returns that instantiation.
|
|
|
|
|
*/
|
|
|
|
|
@@ -8830,6 +8861,7 @@ namespace ts {
|
|
|
|
|
combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
|
|
|
|
|
combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
|
|
|
|
|
combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
|
|
|
|
|
combined & TypeFlags.BigIntLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) ||
|
|
|
|
|
combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
|
|
|
|
|
combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
|
|
|
|
|
return true;
|
|
|
|
|
@@ -8922,6 +8954,7 @@ namespace ts {
|
|
|
|
|
const remove =
|
|
|
|
|
t.flags & TypeFlags.StringLiteral && includes & TypeFlags.String ||
|
|
|
|
|
t.flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number ||
|
|
|
|
|
t.flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt ||
|
|
|
|
|
t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol ||
|
|
|
|
|
t.flags & TypeFlags.Literal && t.flags & TypeFlags.FreshLiteral && containsType(types, (<LiteralType>t).regularType);
|
|
|
|
|
if (remove) {
|
|
|
|
|
@@ -9079,6 +9112,7 @@ namespace ts {
|
|
|
|
|
const remove =
|
|
|
|
|
t.flags & TypeFlags.String && includes & TypeFlags.StringLiteral ||
|
|
|
|
|
t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
|
|
|
|
t.flags & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
|
|
|
|
t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol;
|
|
|
|
|
if (remove) {
|
|
|
|
|
orderedRemoveItemAt(types, i);
|
|
|
|
|
@@ -9094,6 +9128,7 @@ namespace ts {
|
|
|
|
|
if (!containsType(u.types, type)) {
|
|
|
|
|
const primitive = type.flags & TypeFlags.StringLiteral ? stringType :
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral ? numberType :
|
|
|
|
|
type.flags & TypeFlags.BigIntLiteral ? bigintType :
|
|
|
|
|
type.flags & TypeFlags.UniqueESSymbol ? esSymbolType :
|
|
|
|
|
undefined;
|
|
|
|
|
if (!primitive || !containsType(u.types, primitive)) {
|
|
|
|
|
@@ -9170,6 +9205,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral ||
|
|
|
|
|
includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
|
|
|
|
includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
|
|
|
|
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
|
|
|
|
|
removeRedundantPrimitiveTypes(typeSet, includes);
|
|
|
|
|
}
|
|
|
|
|
@@ -9232,13 +9268,24 @@ namespace ts {
|
|
|
|
|
type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getNumericLiteralValue(node: NumericLiteral): number | PseudoBigInt {
|
|
|
|
|
if (node.numericLiteralFlags & TokenFlags.BigInt) {
|
|
|
|
|
return { negative: false, base10Value: parsePseudoBigInt(node.text) };
|
|
|
|
|
}
|
|
|
|
|
return +node.text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getNumericLiteralType(node: NumericLiteral): LiteralType {
|
|
|
|
|
return getLiteralType(getNumericLiteralValue(node));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) {
|
|
|
|
|
if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
|
|
|
|
|
let type = getLateBoundSymbol(prop).nameType;
|
|
|
|
|
if (!type && !isKnownSymbol(prop)) {
|
|
|
|
|
const name = prop.valueDeclaration && getNameOfDeclaration(prop.valueDeclaration);
|
|
|
|
|
type = name && isNumericLiteral(name) ? getLiteralType(+name.text) :
|
|
|
|
|
name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getLiteralType(+name.expression.text) :
|
|
|
|
|
type = name && isNumericLiteral(name) ? getNumericLiteralType(name) :
|
|
|
|
|
name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getNumericLiteralType(name.expression) :
|
|
|
|
|
getLiteralType(symbolName(prop));
|
|
|
|
|
}
|
|
|
|
|
if (type && type.flags & include) {
|
|
|
|
|
@@ -9860,7 +9907,7 @@ namespace ts {
|
|
|
|
|
if (right.flags & TypeFlags.Union) {
|
|
|
|
|
return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags));
|
|
|
|
|
}
|
|
|
|
|
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
|
|
|
|
|
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
|
|
|
|
|
return left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -9968,7 +10015,7 @@ namespace ts {
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createLiteralType(flags: TypeFlags, value: string | number, symbol: Symbol | undefined) {
|
|
|
|
|
function createLiteralType(flags: TypeFlags, value: string | number | PseudoBigInt, symbol: Symbol | undefined) {
|
|
|
|
|
const type = <LiteralType>createType(flags);
|
|
|
|
|
type.symbol = symbol!;
|
|
|
|
|
type.value = value;
|
|
|
|
|
@@ -9993,16 +10040,18 @@ namespace ts {
|
|
|
|
|
type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) {
|
|
|
|
|
function getLiteralType(value: string | number | PseudoBigInt, enumId?: number, symbol?: Symbol) {
|
|
|
|
|
// We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
|
|
|
|
|
// where NNN is the text representation of a numeric literal and SSS are the characters
|
|
|
|
|
// of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
|
|
|
|
|
// EEE is a unique id for the containing enum type.
|
|
|
|
|
const qualifier = typeof value === "number" ? "#" : "@";
|
|
|
|
|
const key = enumId ? enumId + qualifier + value : qualifier + value;
|
|
|
|
|
const qualifier = typeof value === "number" ? "#" : typeof value === "string" ? "@" : "n";
|
|
|
|
|
const key = (enumId ? enumId : "") + qualifier + (typeof value === "object" ? pseudoBigIntToString(value) : value);
|
|
|
|
|
let type = literalTypes.get(key);
|
|
|
|
|
if (!type) {
|
|
|
|
|
const flags = (typeof value === "number" ? TypeFlags.NumberLiteral : TypeFlags.StringLiteral) | (enumId ? TypeFlags.EnumLiteral : 0);
|
|
|
|
|
const flags = (typeof value === "number" ? TypeFlags.NumberLiteral :
|
|
|
|
|
typeof value === "string" ? TypeFlags.StringLiteral : TypeFlags.BigIntLiteral) |
|
|
|
|
|
(enumId ? TypeFlags.EnumLiteral : 0);
|
|
|
|
|
literalTypes.set(key, type = createLiteralType(flags, value, symbol));
|
|
|
|
|
}
|
|
|
|
|
return type;
|
|
|
|
|
@@ -10064,6 +10113,8 @@ namespace ts {
|
|
|
|
|
return stringType;
|
|
|
|
|
case SyntaxKind.NumberKeyword:
|
|
|
|
|
return numberType;
|
|
|
|
|
case SyntaxKind.BigIntKeyword:
|
|
|
|
|
return bigintType;
|
|
|
|
|
case SyntaxKind.BooleanKeyword:
|
|
|
|
|
return booleanType;
|
|
|
|
|
case SyntaxKind.SymbolKeyword:
|
|
|
|
|
@@ -11247,6 +11298,7 @@ namespace ts {
|
|
|
|
|
if (s & TypeFlags.NumberLiteral && s & TypeFlags.EnumLiteral &&
|
|
|
|
|
t & TypeFlags.NumberLiteral && !(t & TypeFlags.EnumLiteral) &&
|
|
|
|
|
(<LiteralType>source).value === (<LiteralType>target).value) return true;
|
|
|
|
|
if (s & TypeFlags.BigIntLike && t & TypeFlags.BigInt) return true;
|
|
|
|
|
if (s & TypeFlags.BooleanLike && t & TypeFlags.Boolean) return true;
|
|
|
|
|
if (s & TypeFlags.ESSymbolLike && t & TypeFlags.ESSymbol) return true;
|
|
|
|
|
if (s & TypeFlags.Enum && t & TypeFlags.Enum && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true;
|
|
|
|
|
@@ -13036,6 +13088,7 @@ namespace ts {
|
|
|
|
|
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
|
|
|
|
|
type.flags & TypeFlags.StringLiteral ? stringType :
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral ? numberType :
|
|
|
|
|
type.flags & TypeFlags.BigIntLiteral ? bigintType :
|
|
|
|
|
type.flags & TypeFlags.BooleanLiteral ? booleanType :
|
|
|
|
|
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getBaseTypeOfLiteralType)) :
|
|
|
|
|
type;
|
|
|
|
|
@@ -13045,6 +13098,7 @@ namespace ts {
|
|
|
|
|
return type.flags & TypeFlags.EnumLiteral && type.flags & TypeFlags.FreshLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
|
|
|
|
|
type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType :
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType :
|
|
|
|
|
type.flags & TypeFlags.BigIntLiteral && type.flags & TypeFlags.FreshLiteral ? bigintType :
|
|
|
|
|
type.flags & TypeFlags.BooleanLiteral && type.flags & TypeFlags.FreshLiteral ? booleanType :
|
|
|
|
|
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
|
|
|
|
|
type;
|
|
|
|
|
@@ -13084,6 +13138,10 @@ namespace ts {
|
|
|
|
|
return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isZeroBigInt({value}: BigIntLiteralType) {
|
|
|
|
|
return value.base10Value === "0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getFalsyFlagsOfTypes(types: Type[]): TypeFlags {
|
|
|
|
|
let result: TypeFlags = 0;
|
|
|
|
|
for (const t of types) {
|
|
|
|
|
@@ -13099,6 +13157,7 @@ namespace ts {
|
|
|
|
|
return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((<UnionType>type).types) :
|
|
|
|
|
type.flags & TypeFlags.StringLiteral ? (<LiteralType>type).value === "" ? TypeFlags.StringLiteral : 0 :
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral ? (<LiteralType>type).value === 0 ? TypeFlags.NumberLiteral : 0 :
|
|
|
|
|
type.flags & TypeFlags.BigIntLiteral ? isZeroBigInt(<BigIntLiteralType>type) ? TypeFlags.BigIntLiteral : 0 :
|
|
|
|
|
type.flags & TypeFlags.BooleanLiteral ? (type === falseType || type === regularFalseType) ? TypeFlags.BooleanLiteral : 0 :
|
|
|
|
|
type.flags & TypeFlags.PossiblyFalsy;
|
|
|
|
|
}
|
|
|
|
|
@@ -13116,11 +13175,13 @@ namespace ts {
|
|
|
|
|
function getDefinitelyFalsyPartOfType(type: Type): Type {
|
|
|
|
|
return type.flags & TypeFlags.String ? emptyStringType :
|
|
|
|
|
type.flags & TypeFlags.Number ? zeroType :
|
|
|
|
|
type.flags & TypeFlags.BigInt ? zeroBigIntType :
|
|
|
|
|
type === regularFalseType ||
|
|
|
|
|
type === falseType ||
|
|
|
|
|
type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) ||
|
|
|
|
|
type.flags & TypeFlags.StringLiteral && (<LiteralType>type).value === "" ||
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral && (<LiteralType>type).value === 0 ? type :
|
|
|
|
|
type.flags & TypeFlags.NumberLiteral && (<LiteralType>type).value === 0 ||
|
|
|
|
|
type.flags & TypeFlags.BigIntLiteral && isZeroBigInt(<BigIntLiteralType>type) ? type :
|
|
|
|
|
neverType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -14498,8 +14559,17 @@ namespace ts {
|
|
|
|
|
if (flags & TypeFlags.NumberLiteral) {
|
|
|
|
|
const isZero = (<LiteralType>type).value === 0;
|
|
|
|
|
return strictNullChecks ?
|
|
|
|
|
isZero ? TypeFacts.ZeroStrictFacts : TypeFacts.NonZeroStrictFacts :
|
|
|
|
|
isZero ? TypeFacts.ZeroFacts : TypeFacts.NonZeroFacts;
|
|
|
|
|
isZero ? TypeFacts.ZeroNumberStrictFacts : TypeFacts.NonZeroNumberStrictFacts :
|
|
|
|
|
isZero ? TypeFacts.ZeroNumberFacts : TypeFacts.NonZeroNumberFacts;
|
|
|
|
|
}
|
|
|
|
|
if (flags & TypeFlags.BigInt) {
|
|
|
|
|
return strictNullChecks ? TypeFacts.BigIntStrictFacts : TypeFacts.BigIntFacts;
|
|
|
|
|
}
|
|
|
|
|
if (flags & TypeFlags.BigIntLiteral) {
|
|
|
|
|
const isZero = isZeroBigInt(<BigIntLiteralType>type);
|
|
|
|
|
return strictNullChecks ?
|
|
|
|
|
isZero ? TypeFacts.ZeroBigIntStrictFacts : TypeFacts.NonZeroBigIntStrictFacts :
|
|
|
|
|
isZero ? TypeFacts.ZeroBigIntFacts : TypeFacts.NonZeroBigIntFacts;
|
|
|
|
|
}
|
|
|
|
|
if (flags & TypeFlags.Boolean) {
|
|
|
|
|
return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts;
|
|
|
|
|
@@ -14810,10 +14880,12 @@ namespace ts {
|
|
|
|
|
// literals in typeWithLiterals, respectively.
|
|
|
|
|
function replacePrimitivesWithLiterals(typeWithPrimitives: Type, typeWithLiterals: Type) {
|
|
|
|
|
if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral) ||
|
|
|
|
|
isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.NumberLiteral)) {
|
|
|
|
|
isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.NumberLiteral) ||
|
|
|
|
|
isTypeSubsetOf(bigintType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.BigIntLiteral)) {
|
|
|
|
|
return mapType(typeWithPrimitives, t =>
|
|
|
|
|
t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral) :
|
|
|
|
|
t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) :
|
|
|
|
|
t.flags & TypeFlags.BigInt ? extractTypesOfKind(typeWithLiterals, TypeFlags.BigInt | TypeFlags.BigIntLiteral) :
|
|
|
|
|
t);
|
|
|
|
|
}
|
|
|
|
|
return typeWithPrimitives;
|
|
|
|
|
@@ -21282,7 +21354,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
|
|
|
|
|
if (!isTypeAssignableToKind(type, TypeFlags.NumberLike)) {
|
|
|
|
|
if (!isTypeAssignableTo(type, numberOrBigIntType)) {
|
|
|
|
|
error(operand, diagnostic);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@@ -21430,10 +21502,19 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
if (node.operand.kind === SyntaxKind.NumericLiteral) {
|
|
|
|
|
if (node.operator === SyntaxKind.MinusToken) {
|
|
|
|
|
return getFreshTypeOfLiteralType(getLiteralType(-(<LiteralExpression>node.operand).text));
|
|
|
|
|
const value = getNumericLiteralValue(node.operand as NumericLiteral);
|
|
|
|
|
return getFreshTypeOfLiteralType(getLiteralType(
|
|
|
|
|
// Keep number as number, bigint as bigint
|
|
|
|
|
typeof value === "number"
|
|
|
|
|
? -value
|
|
|
|
|
: { negative: !value.negative, base10Value: value.base10Value }
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
else if (node.operator === SyntaxKind.PlusToken) {
|
|
|
|
|
return getFreshTypeOfLiteralType(getLiteralType(+(<LiteralExpression>node.operand).text));
|
|
|
|
|
if (isTypeAssignableToKind(operandType, TypeFlags.BigIntLike)) {
|
|
|
|
|
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(operandType));
|
|
|
|
|
}
|
|
|
|
|
return getFreshTypeOfLiteralType(getNumericLiteralType(node.operand as NumericLiteral));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
switch (node.operator) {
|
|
|
|
|
@@ -21444,7 +21525,13 @@ namespace ts {
|
|
|
|
|
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbolLike)) {
|
|
|
|
|
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
|
|
|
|
|
}
|
|
|
|
|
return numberType;
|
|
|
|
|
if (node.operator === SyntaxKind.PlusToken) {
|
|
|
|
|
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
|
|
|
|
|
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(operandType));
|
|
|
|
|
}
|
|
|
|
|
return numberType;
|
|
|
|
|
}
|
|
|
|
|
return getUnaryResultType(operandType);
|
|
|
|
|
case SyntaxKind.ExclamationToken:
|
|
|
|
|
checkTruthinessExpression(node.operand);
|
|
|
|
|
const facts = getTypeFacts(operandType) & (TypeFacts.Truthy | TypeFacts.Falsy);
|
|
|
|
|
@@ -21459,7 +21546,7 @@ namespace ts {
|
|
|
|
|
// run check only if former checks succeeded to avoid reporting cascading errors
|
|
|
|
|
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
|
|
|
|
|
}
|
|
|
|
|
return numberType;
|
|
|
|
|
return getUnaryResultType(operandType);
|
|
|
|
|
}
|
|
|
|
|
return errorType;
|
|
|
|
|
}
|
|
|
|
|
@@ -21477,6 +21564,16 @@ namespace ts {
|
|
|
|
|
// run check only if former checks succeeded to avoid reporting cascading errors
|
|
|
|
|
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
|
|
|
|
|
}
|
|
|
|
|
return getUnaryResultType(operandType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getUnaryResultType(operandType: Type): Type {
|
|
|
|
|
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
|
|
|
|
|
return isTypeAssignableToKind(operandType, TypeFlags.AnyOrUnknown) || maybeTypeOfKind(operandType, TypeFlags.NumberLike)
|
|
|
|
|
? numberOrBigIntType
|
|
|
|
|
: bigintType;
|
|
|
|
|
}
|
|
|
|
|
// If it's not a bigint type, implicit coercion will result in a number
|
|
|
|
|
return numberType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -21505,6 +21602,7 @@ namespace ts {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return !!(kind & TypeFlags.NumberLike) && isTypeAssignableTo(source, numberType) ||
|
|
|
|
|
!!(kind & TypeFlags.BigIntLike) && isTypeAssignableTo(source, bigintType) ||
|
|
|
|
|
!!(kind & TypeFlags.StringLike) && isTypeAssignableTo(source, stringType) ||
|
|
|
|
|
!!(kind & TypeFlags.BooleanLike) && isTypeAssignableTo(source, booleanType) ||
|
|
|
|
|
!!(kind & TypeFlags.Void) && isTypeAssignableTo(source, voidType) ||
|
|
|
|
|
@@ -21869,17 +21967,39 @@ namespace ts {
|
|
|
|
|
(rightType.flags & TypeFlags.BooleanLike) &&
|
|
|
|
|
(suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
|
|
|
|
|
error(errorNode || operatorToken, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator));
|
|
|
|
|
return numberType;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// otherwise just check each operand separately and report errors as normal
|
|
|
|
|
const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
|
|
|
|
|
const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
|
|
|
|
|
if (leftOk && rightOk) {
|
|
|
|
|
checkAssignmentOperator(numberType);
|
|
|
|
|
let resultType: Type;
|
|
|
|
|
// If both are any or unknown, allow operation; assume it will resolve to number
|
|
|
|
|
if ((isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) ||
|
|
|
|
|
// Or, if neither could be bigint, implicit coercion results in a number result
|
|
|
|
|
!(maybeTypeOfKind(leftType, TypeFlags.BigIntLike) || maybeTypeOfKind(rightType, TypeFlags.BigIntLike))
|
|
|
|
|
) {
|
|
|
|
|
resultType = numberType;
|
|
|
|
|
}
|
|
|
|
|
// At least one is assignable to bigint, so both should be only assignable to bigint
|
|
|
|
|
else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike)) {
|
|
|
|
|
switch (operator) {
|
|
|
|
|
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
|
|
|
|
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
|
|
|
|
reportOperatorError();
|
|
|
|
|
}
|
|
|
|
|
resultType = bigintType;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
reportOperatorError();
|
|
|
|
|
resultType = errorType;
|
|
|
|
|
}
|
|
|
|
|
if (leftOk && rightOk) {
|
|
|
|
|
checkAssignmentOperator(resultType);
|
|
|
|
|
}
|
|
|
|
|
return resultType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return numberType;
|
|
|
|
|
case SyntaxKind.PlusToken:
|
|
|
|
|
case SyntaxKind.PlusEqualsToken:
|
|
|
|
|
if (leftType === silentNeverType || rightType === silentNeverType) {
|
|
|
|
|
@@ -21897,6 +22017,10 @@ namespace ts {
|
|
|
|
|
// If both operands are of the Number primitive type, the result is of the Number primitive type.
|
|
|
|
|
resultType = numberType;
|
|
|
|
|
}
|
|
|
|
|
else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike, /*strict*/ true) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike, /*strict*/ true)) {
|
|
|
|
|
// If both operands are of the BigInt primitive type, the result is of the BigInt primitive type.
|
|
|
|
|
resultType = bigintType;
|
|
|
|
|
}
|
|
|
|
|
else if (isTypeAssignableToKind(leftType, TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, TypeFlags.StringLike, /*strict*/ true)) {
|
|
|
|
|
// If one or both operands are of the String primitive type, the result is of the String primitive type.
|
|
|
|
|
resultType = stringType;
|
|
|
|
|
@@ -21928,7 +22052,9 @@ namespace ts {
|
|
|
|
|
if (checkForDisallowedESSymbolOperand(operator)) {
|
|
|
|
|
leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
|
|
|
|
|
rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
|
|
|
|
|
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
|
|
|
|
|
if (!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
|
|
|
|
|
(isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType))
|
|
|
|
|
)) {
|
|
|
|
|
reportOperatorError();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -22259,6 +22385,7 @@ namespace ts {
|
|
|
|
|
const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
|
|
|
|
|
return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
|
|
|
|
|
maybeTypeOfKind(constraint, TypeFlags.Number) && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
|
|
|
|
|
maybeTypeOfKind(constraint, TypeFlags.BigInt) && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
|
|
|
|
|
maybeTypeOfKind(constraint, TypeFlags.ESSymbol) && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) ||
|
|
|
|
|
isLiteralOfContextualType(candidateType, constraint);
|
|
|
|
|
}
|
|
|
|
|
@@ -22266,6 +22393,7 @@ namespace ts {
|
|
|
|
|
// literal context for all literals of that primitive type.
|
|
|
|
|
return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
|
|
|
|
|
contextualType.flags & TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
|
|
|
|
|
contextualType.flags & TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
|
|
|
|
|
contextualType.flags & TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) ||
|
|
|
|
|
contextualType.flags & TypeFlags.UniqueESSymbol && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol));
|
|
|
|
|
}
|
|
|
|
|
@@ -22427,7 +22555,7 @@ namespace ts {
|
|
|
|
|
return getFreshTypeOfLiteralType(getLiteralType((node as StringLiteralLike).text));
|
|
|
|
|
case SyntaxKind.NumericLiteral:
|
|
|
|
|
checkGrammarNumericLiteral(node as NumericLiteral);
|
|
|
|
|
return getFreshTypeOfLiteralType(getLiteralType(+(node as NumericLiteral).text));
|
|
|
|
|
return getFreshTypeOfLiteralType(getNumericLiteralType(node as NumericLiteral));
|
|
|
|
|
case SyntaxKind.TrueKeyword:
|
|
|
|
|
return trueType;
|
|
|
|
|
case SyntaxKind.FalseKeyword:
|
|
|
|
|
@@ -25835,6 +25963,7 @@ namespace ts {
|
|
|
|
|
case "any":
|
|
|
|
|
case "unknown":
|
|
|
|
|
case "number":
|
|
|
|
|
case "bigint":
|
|
|
|
|
case "boolean":
|
|
|
|
|
case "string":
|
|
|
|
|
case "symbol":
|
|
|
|
|
@@ -26463,7 +26592,8 @@ namespace ts {
|
|
|
|
|
return (<StringLiteral>expr).text;
|
|
|
|
|
case SyntaxKind.NumericLiteral:
|
|
|
|
|
checkGrammarNumericLiteral(<NumericLiteral>expr);
|
|
|
|
|
return +(<NumericLiteral>expr).text;
|
|
|
|
|
const literalValue = getNumericLiteralValue(<NumericLiteral>expr);
|
|
|
|
|
return typeof literalValue === "number" ? literalValue : undefined; // don't evaluate bigint
|
|
|
|
|
case SyntaxKind.ParenthesizedExpression:
|
|
|
|
|
return evaluate((<ParenthesizedExpression>expr).expression);
|
|
|
|
|
case SyntaxKind.Identifier:
|
|
|
|
|
@@ -28517,6 +28647,9 @@ namespace ts {
|
|
|
|
|
else if (isTypeAssignableToKind(type, TypeFlags.NumberLike)) {
|
|
|
|
|
return TypeReferenceSerializationKind.NumberLikeType;
|
|
|
|
|
}
|
|
|
|
|
else if (isTypeAssignableToKind(type, TypeFlags.BigIntLike)) {
|
|
|
|
|
return TypeReferenceSerializationKind.BigIntLikeType;
|
|
|
|
|
}
|
|
|
|
|
else if (isTypeAssignableToKind(type, TypeFlags.StringLike)) {
|
|
|
|
|
return TypeReferenceSerializationKind.StringLikeType;
|
|
|
|
|
}
|
|
|
|
|
|