Add bigint type

This commit is contained in:
Caleb Sander
2018-09-29 14:02:44 -07:00
parent 3e10dedbce
commit ac2a118f07
6 changed files with 254 additions and 98 deletions

View File

@@ -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;
}

View File

@@ -68,13 +68,18 @@ namespace ts {
/* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // tslint:disable-line unified-signatures
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
export function createLiteral(value: number): NumericLiteral;
export function createLiteral(value: number | PseudoBigInt): NumericLiteral;
export function createLiteral(value: boolean): BooleanLiteral;
export function createLiteral(value: string | number | boolean): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression;
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
if (typeof value === "number") {
return createNumericLiteral(value + "");
}
if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
const literal = createNumericLiteral(pseudoBigIntToString(value) + "n");
literal.numericLiteralFlags |= TokenFlags.BigInt;
return literal;
}
if (typeof value === "boolean") {
return value ? createTrue() : createFalse();
}

View File

@@ -2006,6 +2006,9 @@ namespace ts {
case TypeReferenceSerializationKind.VoidNullableOrNeverType:
return createVoidZero();
case TypeReferenceSerializationKind.BigIntLikeType:
return createIdentifier("BigInt");
case TypeReferenceSerializationKind.BooleanType:
return createIdentifier("Boolean");

View File

@@ -271,6 +271,7 @@ namespace ts {
UnknownKeyword,
FromKeyword,
GlobalKeyword,
BigIntKeyword,
OfKeyword, // LastKeyword and LastToken and LastContextualKeyword
// Parse tree nodes
@@ -1109,6 +1110,7 @@ namespace ts {
kind: SyntaxKind.AnyKeyword
| SyntaxKind.UnknownKeyword
| SyntaxKind.NumberKeyword
| SyntaxKind.BigIntKeyword
| SyntaxKind.ObjectKeyword
| SyntaxKind.BooleanKeyword
| SyntaxKind.StringKeyword
@@ -1658,8 +1660,9 @@ namespace ts {
BinarySpecifier = 1 << 7, // e.g. `0b0110010000000000`
OctalSpecifier = 1 << 8, // e.g. `0o777`
ContainsSeparator = 1 << 9, // e.g. `0b1100_0101`
BigInt = 1 << 10, // e.g. `123n`
BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier,
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier | ContainsSeparator
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator | BigInt
}
export interface NumericLiteral extends LiteralExpression {
@@ -3461,6 +3464,7 @@ namespace ts {
// of a type, such as the global `Promise` type in lib.d.ts).
VoidNullableOrNeverType, // The TypeReferenceNode resolves to a Void-like, Nullable, or Never type.
NumberLikeType, // The TypeReferenceNode resolves to a Number-like type.
BigIntLikeType, // The TypeReferenceNode resolves to a BigInt-like type.
StringLikeType, // The TypeReferenceNode resolves to a String-like type.
BooleanType, // The TypeReferenceNode resolves to a Boolean-like type.
ArrayLikeType, // The TypeReferenceNode resolves to an Array-like type.
@@ -3805,60 +3809,63 @@ namespace ts {
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5,
StringLiteral = 1 << 6,
NumberLiteral = 1 << 7,
BooleanLiteral = 1 << 8,
EnumLiteral = 1 << 9, // Always combined with StringLiteral, NumberLiteral, or Union
ESSymbol = 1 << 10, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 11, // unique symbol
Void = 1 << 12,
Undefined = 1 << 13,
Null = 1 << 14,
Never = 1 << 15, // Never type
TypeParameter = 1 << 16, // Type parameter
Object = 1 << 17, // Object type
Union = 1 << 18, // Union (T | U)
Intersection = 1 << 19, // Intersection (T & U)
Index = 1 << 20, // keyof T
IndexedAccess = 1 << 21, // T[K]
Conditional = 1 << 22, // T extends U ? X : Y
Substitution = 1 << 23, // Type parameter substitution
NonPrimitive = 1 << 24, // intrinsic object type
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
/* @internal */
FreshLiteral = 1 << 25, // Fresh literal or unique type
FreshLiteral = 1 << 27, // Fresh literal or unique type
/* @internal */
UnionOfPrimitiveTypes = 1 << 26, // Type is union of primitive types
UnionOfPrimitiveTypes = 1 << 28, // Type is union of primitive types
/* @internal */
ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type
ContainsWideningType = 1 << 29, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 28, // Type is or contains object literal type
ContainsObjectLiteral = 1 << 30, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 29, // Type is or contains the anyFunctionType
ContainsAnyFunctionType = 1 << 31, // Type is or contains the anyFunctionType
/* @internal */
AnyOrUnknown = Any | Unknown,
/* @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BooleanLiteral,
Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral,
Unit = Literal | UniqueESSymbol | Nullable,
StringOrNumberLiteral = StringLiteral | NumberLiteral,
/* @internal */
StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol,
/* @internal */
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
PossiblyFalsy = DefinitelyFalsy | String | Number | Boolean,
DefinitelyFalsy = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral | Void | Undefined | Null,
PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean,
/* @internal */
Intrinsic = Any | Unknown | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
/* @internal */
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
StringLike = String | StringLiteral,
NumberLike = Number | NumberLiteral | Enum,
BigIntLike = BigInt | BigIntLiteral,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
VoidLike = Void | Undefined,
/* @internal */
DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null,
DisjointDomains = NonPrimitive | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbolLike | VoidLike | Null,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess,
@@ -3869,7 +3876,7 @@ namespace ts {
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive,
/* @internal */
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
@@ -3926,10 +3933,11 @@ namespace ts {
// String literal types (TypeFlags.StringLiteral)
// Numeric literal types (TypeFlags.NumberLiteral)
// BigInt literal types (TypeFlags.BigIntLiteral)
export interface LiteralType extends Type {
value: string | number; // Value of literal
freshType: LiteralType; // Fresh version of type
regularType: LiteralType; // Regular version of type
value: string | number | PseudoBigInt; // Value of literal
freshType: LiteralType; // Fresh version of type
regularType: LiteralType; // Regular version of type
}
// Unique symbol types (TypeFlags.UniqueESSymbol)
@@ -3945,6 +3953,10 @@ namespace ts {
value: number;
}
export interface BigIntLiteralType extends LiteralType {
value: PseudoBigInt;
}
// Enum types (TypeFlags.Enum)
export interface EnumType extends Type {
}

View File

@@ -976,6 +976,7 @@ namespace ts {
case SyntaxKind.AnyKeyword:
case SyntaxKind.UnknownKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BigIntKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
@@ -6214,6 +6215,7 @@ namespace ts {
|| kind === SyntaxKind.AnyKeyword
|| kind === SyntaxKind.UnknownKeyword
|| kind === SyntaxKind.NumberKeyword
|| kind === SyntaxKind.BigIntKeyword
|| kind === SyntaxKind.ObjectKeyword
|| kind === SyntaxKind.BooleanKeyword
|| kind === SyntaxKind.StringKeyword

View File

@@ -165,8 +165,9 @@ namespace ts.Completions {
});
}
const completionNameForLiteral = JSON.stringify;
function createCompletionEntryForLiteral(literal: string | number): CompletionEntry {
const completionNameForLiteral = (literal: string | number | PseudoBigInt) =>
typeof literal === "object" ? pseudoBigIntToString(literal) + "n" : JSON.stringify(literal);
function createCompletionEntryForLiteral(literal: string | number | PseudoBigInt): CompletionEntry {
return { name: completionNameForLiteral(literal), kind: ScriptElementKind.string, kindModifiers: ScriptElementKindModifier.none, sortText: "0" };
}
@@ -337,7 +338,7 @@ namespace ts.Completions {
readonly isJsxInitializer: IsJsxInitializer;
}
function getSymbolCompletionFromEntryId(program: Program, log: Log, sourceFile: SourceFile, position: number, entryId: CompletionEntryIdentifier,
): SymbolCompletion | { type: "request", request: Request } | { type: "literal", literal: string | number } | { type: "none" } {
): SymbolCompletion | { type: "request", request: Request } | { type: "literal", literal: string | number | PseudoBigInt } | { type: "none" } {
const compilerOptions = program.getCompilerOptions();
const completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }, entryId);
if (!completionData) {
@@ -502,7 +503,7 @@ namespace ts.Completions {
readonly isNewIdentifierLocation: boolean;
readonly location: Node | undefined;
readonly keywordFilters: KeywordCompletionFilters;
readonly literals: ReadonlyArray<string | number>;
readonly literals: ReadonlyArray<string | number | PseudoBigInt>;
readonly symbolToOriginInfoMap: SymbolOriginInfoMap;
readonly recommendedCompletion: Symbol | undefined;
readonly previousToken: Node | undefined;