@@ -13187,7 +13187,7 @@ namespace ts {
13187
13187
i--;
13188
13188
const t = types[i];
13189
13189
const remove =
13190
- t.flags & TypeFlags.StringLiteral && includes & TypeFlags.String ||
13190
+ t.flags & TypeFlags.StringLikeLiteral && includes & TypeFlags.String ||
13191
13191
t.flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number ||
13192
13192
t.flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt ||
13193
13193
t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol ||
@@ -13234,7 +13234,7 @@ namespace ts {
13234
13234
}
13235
13235
switch (unionReduction) {
13236
13236
case UnionReduction.Literal:
13237
- if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol)) {
13237
+ if (includes & (TypeFlags.FreshableLiteral | TypeFlags.UniqueESSymbol)) {
13238
13238
removeRedundantLiteralTypes(typeSet, includes);
13239
13239
}
13240
13240
if (includes & TypeFlags.StringLiteral && includes & TypeFlags.TemplateLiteral) {
@@ -13765,6 +13765,7 @@ namespace ts {
13765
13765
let type = templateLiteralTypes.get(id);
13766
13766
if (!type) {
13767
13767
templateLiteralTypes.set(id, type = createTemplateLiteralType(newTexts, newTypes));
13768
+ type.regularType = type;
13768
13769
}
13769
13770
return type;
13770
13771
@@ -14803,26 +14804,28 @@ namespace ts {
14803
14804
}
14804
14805
14805
14806
function getFreshTypeOfLiteralType(type: Type): Type {
14806
- if (type.flags & TypeFlags.Literal) {
14807
- if (!(<LiteralType>type).freshType) {
14808
- const freshType = createLiteralType(type.flags, (<LiteralType>type).value, (<LiteralType>type).symbol);
14809
- freshType.regularType = <LiteralType>type;
14807
+ if (type.flags & TypeFlags.FreshableLiteral) {
14808
+ if (!(<FreshableLiteralType>type).freshType) {
14809
+ const freshType = type.flags & TypeFlags.TemplateLiteral ?
14810
+ createTemplateLiteralType((<TemplateLiteralType>type).texts, (<TemplateLiteralType>type).types) :
14811
+ createLiteralType(type.flags, (<LiteralType>type).value, (<LiteralType>type).symbol);
14812
+ freshType.regularType = <FreshableLiteralType>type;
14810
14813
freshType.freshType = freshType;
14811
- (<LiteralType >type).freshType = freshType;
14814
+ (<FreshableLiteralType >type).freshType = freshType;
14812
14815
}
14813
- return (<LiteralType >type).freshType;
14816
+ return (<FreshableLiteralType >type).freshType;
14814
14817
}
14815
14818
return type;
14816
14819
}
14817
14820
14818
14821
function getRegularTypeOfLiteralType(type: Type): Type {
14819
- return type.flags & TypeFlags.Literal ? (<LiteralType >type).regularType :
14822
+ return type.flags & TypeFlags.FreshableLiteral ? (<FreshableLiteralType >type).regularType :
14820
14823
type.flags & TypeFlags.Union ? ((<UnionType>type).regularType || ((<UnionType>type).regularType = getUnionType(sameMap((<UnionType>type).types, getRegularTypeOfLiteralType)) as UnionType)) :
14821
14824
type;
14822
14825
}
14823
14826
14824
14827
function isFreshLiteralType(type: Type) {
14825
- return !!(type.flags & TypeFlags.Literal ) && (<LiteralType >type).freshType === type;
14828
+ return !!(type.flags & TypeFlags.FreshableLiteral ) && (<FreshableLiteralType >type).freshType === type;
14826
14829
}
14827
14830
14828
14831
function getLiteralType(value: string): StringLiteralType;
@@ -17694,17 +17697,20 @@ namespace ts {
17694
17697
}
17695
17698
}
17696
17699
else if (source.flags & TypeFlags.TemplateLiteral) {
17697
- if (target.flags & TypeFlags.TemplateLiteral &&
17698
- (source as TemplateLiteralType).texts.length === (target as TemplateLiteralType).texts.length &&
17699
- (source as TemplateLiteralType).types.length === (target as TemplateLiteralType).types.length &&
17700
- every((source as TemplateLiteralType).texts, (t, i) => t === (target as TemplateLiteralType).texts[i]) &&
17701
- every((instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)) as TemplateLiteralType).types, (t, i) => !!((target as TemplateLiteralType).types[i].flags & (TypeFlags.Any | TypeFlags.String)) || !!isRelatedTo(t, (target as TemplateLiteralType).types[i], /*reportErrors*/ false))) {
17702
- return Ternary.True;
17700
+ if (target.flags & TypeFlags.TemplateLiteral) {
17701
+ if ((source as TemplateLiteralType).texts.length === (target as TemplateLiteralType).texts.length &&
17702
+ (source as TemplateLiteralType).types.length === (target as TemplateLiteralType).types.length &&
17703
+ every((source as TemplateLiteralType).texts, (t, i) => t === (target as TemplateLiteralType).texts[i]) &&
17704
+ every((instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)) as TemplateLiteralType).types, (t, i) => !!((target as TemplateLiteralType).types[i].flags & (TypeFlags.Any | TypeFlags.String)) || !!isRelatedTo(t, (target as TemplateLiteralType).types[i], /*reportErrors*/ false))) {
17705
+ return Ternary.True;
17706
+ }
17703
17707
}
17704
- const constraint = getBaseConstraintOfType(source);
17705
- if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, reportErrors))) {
17706
- resetErrorInfo(saveErrorInfo);
17707
- return result;
17708
+ else {
17709
+ const constraint = getBaseConstraintOfType(source);
17710
+ if (result = isRelatedTo(constraint && constraint !== source ? constraint : stringType, target, reportErrors)) {
17711
+ resetErrorInfo(saveErrorInfo);
17712
+ return result;
17713
+ }
17708
17714
}
17709
17715
}
17710
17716
else if (source.flags & TypeFlags.StringMapping) {
@@ -19181,7 +19187,7 @@ namespace ts {
19181
19187
19182
19188
function getBaseTypeOfLiteralType(type: Type): Type {
19183
19189
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
19184
- type.flags & TypeFlags.StringLiteral ? stringType :
19190
+ type.flags & TypeFlags.StringLikeLiteral ? stringType :
19185
19191
type.flags & TypeFlags.NumberLiteral ? numberType :
19186
19192
type.flags & TypeFlags.BigIntLiteral ? bigintType :
19187
19193
type.flags & TypeFlags.BooleanLiteral ? booleanType :
@@ -19191,7 +19197,7 @@ namespace ts {
19191
19197
19192
19198
function getWidenedLiteralType(type: Type): Type {
19193
19199
return type.flags & TypeFlags.EnumLiteral && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
19194
- type.flags & TypeFlags.StringLiteral && isFreshLiteralType(type) ? stringType :
19200
+ type.flags & TypeFlags.StringLikeLiteral && isFreshLiteralType(type) ? stringType :
19195
19201
type.flags & TypeFlags.NumberLiteral && isFreshLiteralType(type) ? numberType :
19196
19202
type.flags & TypeFlags.BigIntLiteral && isFreshLiteralType(type) ? bigintType :
19197
19203
type.flags & TypeFlags.BooleanLiteral && isFreshLiteralType(type) ? booleanType :
@@ -20692,7 +20698,7 @@ namespace ts {
20692
20698
}
20693
20699
20694
20700
function isTypeOrBaseIdenticalTo(s: Type, t: Type) {
20695
- return isTypeIdenticalTo(s, t) || !!(t.flags & TypeFlags.String && s.flags & TypeFlags.StringLiteral || t.flags & TypeFlags.Number && s.flags & TypeFlags.NumberLiteral);
20701
+ return isTypeIdenticalTo(s, t) || !!(t.flags & TypeFlags.String && s.flags & TypeFlags.StringLikeLiteral || t.flags & TypeFlags.Number && s.flags & TypeFlags.NumberLiteral);
20696
20702
}
20697
20703
20698
20704
function isTypeCloselyMatchedBy(s: Type, t: Type) {
@@ -30837,7 +30843,7 @@ namespace ts {
30837
30843
texts.push(span.literal.text);
30838
30844
types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType);
30839
30845
}
30840
- return isConstContext(node) ? getTemplateLiteralType(texts, types) : stringType ;
30846
+ return getFreshTypeOfLiteralType( getTemplateLiteralType(texts, types)) ;
30841
30847
}
30842
30848
30843
30849
function getContextNode(node: Expression): Node {
@@ -30858,7 +30864,7 @@ namespace ts {
30858
30864
// We strip literal freshness when an appropriate contextual type is present such that contextually typed
30859
30865
// literals always preserve their literal types (otherwise they might widen during type inference). An alternative
30860
30866
// here would be to not mark contextually typed literals as fresh in the first place.
30861
- const result = maybeTypeOfKind(type, TypeFlags.Literal ) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ?
30867
+ const result = maybeTypeOfKind(type, TypeFlags.FreshableLiteral ) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ?
30862
30868
getRegularTypeOfLiteralType(type) : type;
30863
30869
return result;
30864
30870
}
@@ -30948,15 +30954,15 @@ namespace ts {
30948
30954
// this a literal context for literals of that primitive type. For example, given a
30949
30955
// type parameter 'T extends string', infer string literal types for T.
30950
30956
const constraint = getBaseConstraintOfType(contextualType) || unknownType;
30951
- return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral ) ||
30957
+ return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLikeLiteral ) ||
30952
30958
maybeTypeOfKind(constraint, TypeFlags.Number) && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
30953
30959
maybeTypeOfKind(constraint, TypeFlags.BigInt) && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
30954
30960
maybeTypeOfKind(constraint, TypeFlags.ESSymbol) && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) ||
30955
30961
isLiteralOfContextualType(candidateType, constraint);
30956
30962
}
30957
30963
// If the contextual type is a literal of a particular primitive type, we consider this a
30958
30964
// literal context for all literals of that primitive type.
30959
- return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags. StringMapping) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral ) ||
30965
+ return !!(contextualType.flags & (TypeFlags.StringLikeLiteral | TypeFlags.Index | TypeFlags.StringMapping) && maybeTypeOfKind(candidateType, TypeFlags.StringLikeLiteral ) ||
30960
30966
contextualType.flags & TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
30961
30967
contextualType.flags & TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
30962
30968
contextualType.flags & TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) ||
@@ -38482,7 +38488,8 @@ namespace ts {
38482
38488
38483
38489
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
38484
38490
if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) {
38485
- return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node)));
38491
+ const type = getTypeOfSymbol(getSymbolOfNode(node));
38492
+ return !!(type.flags & TypeFlags.Literal) && isFreshLiteralType(type);
38486
38493
}
38487
38494
return false;
38488
38495
}
0 commit comments