@@ -408,11 +408,13 @@ namespace ts {
408
408
const regularFalseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false") as FreshableIntrinsicType;
409
409
const trueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true") as FreshableIntrinsicType;
410
410
const regularTrueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true") as FreshableIntrinsicType;
411
- falseType.flags |= TypeFlags.FreshLiteral;
412
- trueType.flags |= TypeFlags.FreshLiteral;
413
411
trueType.regularType = regularTrueType;
412
+ trueType.freshType = trueType;
413
+ regularTrueType.regularType = regularTrueType;
414
414
regularTrueType.freshType = trueType;
415
415
falseType.regularType = regularFalseType;
416
+ falseType.freshType = falseType;
417
+ regularFalseType.regularType = regularFalseType;
416
418
regularFalseType.freshType = falseType;
417
419
const booleanType = createBooleanType([regularFalseType, regularTrueType]);
418
420
// Also mark all combinations of fresh/regular booleans as "Boolean" so they print as `boolean` instead of `true | false`
@@ -8969,7 +8971,7 @@ namespace ts {
8969
8971
t.flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number ||
8970
8972
t.flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt ||
8971
8973
t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol ||
8972
- t.flags & TypeFlags.Literal && t.flags & TypeFlags.FreshLiteral && containsType(types, (<LiteralType>t).regularType);
8974
+ isFreshLiteralType(t) && containsType(types, (<LiteralType>t).regularType);
8973
8975
if (remove) {
8974
8976
orderedRemoveItemAt(types, i);
8975
8977
}
@@ -10039,10 +10041,11 @@ namespace ts {
10039
10041
}
10040
10042
10041
10043
function getFreshTypeOfLiteralType(type: Type): Type {
10042
- if (type.flags & TypeFlags.Literal && !(type.flags & TypeFlags.FreshLiteral) ) {
10043
- if (!(<LiteralType>type).freshType) { // NOTE: Safe because all freshable intrinsics always have fresh types already
10044
- const freshType = createLiteralType(type.flags | TypeFlags.FreshLiteral , (<LiteralType>type).value, (<LiteralType>type).symbol);
10044
+ if (type.flags & TypeFlags.Literal) {
10045
+ if (!(<LiteralType>type).freshType) {
10046
+ const freshType = createLiteralType(type.flags, (<LiteralType>type).value, (<LiteralType>type).symbol);
10045
10047
freshType.regularType = <LiteralType>type;
10048
+ freshType.freshType = freshType;
10046
10049
(<LiteralType>type).freshType = freshType;
10047
10050
}
10048
10051
return (<LiteralType>type).freshType;
@@ -10051,11 +10054,15 @@ namespace ts {
10051
10054
}
10052
10055
10053
10056
function getRegularTypeOfLiteralType(type: Type): Type {
10054
- return type.flags & TypeFlags.Literal && type.flags & TypeFlags.FreshLiteral ? (<LiteralType>type).regularType :
10057
+ return type.flags & TypeFlags.Literal ? (<LiteralType>type).regularType :
10055
10058
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getRegularTypeOfLiteralType)) :
10056
10059
type;
10057
10060
}
10058
10061
10062
+ function isFreshLiteralType(type: Type) {
10063
+ return !!(type.flags & TypeFlags.Literal) && (<LiteralType>type).freshType === type;
10064
+ }
10065
+
10059
10066
function getLiteralType(value: string | number | PseudoBigInt, enumId?: number, symbol?: Symbol) {
10060
10067
// We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
10061
10068
// where NNN is the text representation of a numeric literal and SSS are the characters
@@ -10069,6 +10076,7 @@ namespace ts {
10069
10076
typeof value === "string" ? TypeFlags.StringLiteral : TypeFlags.BigIntLiteral) |
10070
10077
(enumId ? TypeFlags.EnumLiteral : 0);
10071
10078
literalTypes.set(key, type = createLiteralType(flags, value, symbol));
10079
+ type.regularType = type;
10072
10080
}
10073
10081
return type;
10074
10082
}
@@ -11340,10 +11348,10 @@ namespace ts {
11340
11348
}
11341
11349
11342
11350
function isTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>) {
11343
- if (source.flags & TypeFlags.Literal && source.flags & TypeFlags.FreshLiteral ) {
11351
+ if (isFreshLiteralType( source) ) {
11344
11352
source = (<FreshableType>source).regularType;
11345
11353
}
11346
- if (target.flags & TypeFlags.Literal && target.flags & TypeFlags.FreshLiteral ) {
11354
+ if (isFreshLiteralType( target) ) {
11347
11355
target = (<FreshableType>target).regularType;
11348
11356
}
11349
11357
if (source === target ||
@@ -11498,10 +11506,10 @@ namespace ts {
11498
11506
* * Ternary.False if they are not related.
11499
11507
*/
11500
11508
function isRelatedTo(source: Type, target: Type, reportErrors = false, headMessage?: DiagnosticMessage, isApparentIntersectionConstituent?: boolean): Ternary {
11501
- if (source.flags & TypeFlags.Literal && source.flags & TypeFlags.FreshLiteral ) {
11509
+ if (isFreshLiteralType( source) ) {
11502
11510
source = (<FreshableType>source).regularType;
11503
11511
}
11504
- if (target.flags & TypeFlags.Literal && target.flags & TypeFlags.FreshLiteral ) {
11512
+ if (isFreshLiteralType( target) ) {
11505
11513
target = (<FreshableType>target).regularType;
11506
11514
}
11507
11515
if (source.flags & TypeFlags.Substitution) {
@@ -13113,11 +13121,11 @@ namespace ts {
13113
13121
}
13114
13122
13115
13123
function getWidenedLiteralType(type: Type): Type {
13116
- return type.flags & TypeFlags.EnumLiteral && type.flags & TypeFlags.FreshLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
13117
- type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType :
13118
- type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType :
13119
- type.flags & TypeFlags.BigIntLiteral && type.flags & TypeFlags.FreshLiteral ? bigintType :
13120
- type.flags & TypeFlags.BooleanLiteral && type.flags & TypeFlags.FreshLiteral ? booleanType :
13124
+ return type.flags & TypeFlags.EnumLiteral && isFreshLiteralType( type) ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
13125
+ type.flags & TypeFlags.StringLiteral && isFreshLiteralType( type) ? stringType :
13126
+ type.flags & TypeFlags.NumberLiteral && isFreshLiteralType( type) ? numberType :
13127
+ type.flags & TypeFlags.BigIntLiteral && isFreshLiteralType( type) ? bigintType :
13128
+ type.flags & TypeFlags.BooleanLiteral && isFreshLiteralType( type) ? booleanType :
13121
13129
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
13122
13130
type;
13123
13131
}
@@ -14530,7 +14538,7 @@ namespace ts {
14530
14538
return assignedType;
14531
14539
}
14532
14540
let reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
14533
- if (assignedType.flags & TypeFlags.FreshLiteral && assignedType.flags & TypeFlags.BooleanLiteral ) {
14541
+ if (assignedType.flags & TypeFlags.BooleanLiteral && isFreshLiteralType( assignedType) ) {
14534
14542
reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types
14535
14543
}
14536
14544
// Our crude heuristic produces an invalid result in some cases: see GH#26130.
@@ -28768,8 +28776,7 @@ namespace ts {
28768
28776
28769
28777
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
28770
28778
if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) {
28771
- const type = getTypeOfSymbol(getSymbolOfNode(node));
28772
- return !!(type.flags & TypeFlags.Literal && type.flags & TypeFlags.FreshLiteral);
28779
+ return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node)));
28773
28780
}
28774
28781
return false;
28775
28782
}
0 commit comments