@@ -16582,7 +16582,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16582
16582
for (const u of unionTypes) {
16583
16583
if (!containsType(u.types, type)) {
16584
16584
const primitive = type.flags & TypeFlags.StringLiteral ? stringType :
16585
- type.flags & TypeFlags.NumberLiteral ? numberType :
16585
+ type.flags & ( TypeFlags.Enum | TypeFlags. NumberLiteral) ? numberType :
16586
16586
type.flags & TypeFlags.BigIntLiteral ? bigintType :
16587
16587
type.flags & TypeFlags.UniqueESSymbol ? esSymbolType :
16588
16588
undefined;
@@ -16618,10 +16618,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16618
16618
return false;
16619
16619
}
16620
16620
16621
- function eachIsUnionContaining(types: Type[], flag: TypeFlags) {
16622
- return every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag)));
16623
- }
16624
-
16625
16621
function removeFromEach(types: Type[], flag: TypeFlags) {
16626
16622
for (let i = 0; i < types.length; i++) {
16627
16623
types[i] = filterType(types[i], t => !(t.flags & flag));
@@ -16753,12 +16749,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16753
16749
// reduced we'll never reduce again, so this occurs at most once.
16754
16750
result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
16755
16751
}
16756
- else if (eachIsUnionContaining (typeSet, TypeFlags.Undefined)) {
16752
+ else if (every (typeSet, t => !!(t.flags & TypeFlags.Union && (t as UnionType).types[0].flags & TypeFlags. Undefined) )) {
16757
16753
const containedUndefinedType = some(typeSet, containsMissingType) ? missingType : undefinedType;
16758
16754
removeFromEach(typeSet, TypeFlags.Undefined);
16759
16755
result = getUnionType([getIntersectionType(typeSet), containedUndefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
16760
16756
}
16761
- else if (eachIsUnionContaining (typeSet, TypeFlags.Null)) {
16757
+ else if (every (typeSet, t => !!(t.flags & TypeFlags.Union && ((t as UnionType).types[0].flags & TypeFlags. Null || (t as UnionType).types[1].flags & TypeFlags.Null)) )) {
16762
16758
removeFromEach(typeSet, TypeFlags.Null);
16763
16759
result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
16764
16760
}
@@ -20855,6 +20851,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
20855
20851
if (containsType(targetTypes, source)) {
20856
20852
return Ternary.True;
20857
20853
}
20854
+ if (getObjectFlags(target) & ObjectFlags.PrimitiveUnion && !(source.flags & TypeFlags.EnumLiteral) && (
20855
+ source.flags & (TypeFlags.StringLiteral | TypeFlags.BooleanLiteral | TypeFlags.BigIntLiteral) ||
20856
+ (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & TypeFlags.NumberLiteral)) {
20857
+ // When relating a literal type to a union of primitive types, we know the relation is false unless
20858
+ // the union contains the base primitive type or the literal type in one of its fresh/regular forms.
20859
+ // We exclude numeric literals for non-subtype relations because numeric literals are assignable to
20860
+ // numeric enum literals with the same value. Similarly, we exclude enum literal types because
20861
+ // identically named enum types are related (see isEmumTypeRelatedTo).
20862
+ const alternateForm = source === (source as StringLiteralType).regularType ? (source as StringLiteralType).freshType : (source as StringLiteralType).regularType;
20863
+ const primitive = source.flags & TypeFlags.StringLiteral ? stringType :
20864
+ source.flags & TypeFlags.NumberLiteral ? numberType :
20865
+ source.flags & TypeFlags.BigIntLiteral ? bigintType :
20866
+ undefined;
20867
+ return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? Ternary.True : Ternary.False;
20868
+ }
20858
20869
const match = getMatchingUnionConstituentForType(target as UnionType, source);
20859
20870
if (match) {
20860
20871
const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false);
0 commit comments