mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
Properly handle tagged primitives in control flow analysis (#43538)
* Ignore object types in intersections with primitive types * Add regression test * Also handle instantiable types constrained to object types * Add another test * Add ignoreObjects optional parameter to getTypeFacts
This commit is contained in:
@@ -21965,7 +21965,7 @@ namespace ts {
|
||||
resolved.members.get("bind" as __String) && isTypeSubtypeOf(type, globalFunctionType));
|
||||
}
|
||||
|
||||
function getTypeFacts(type: Type): TypeFacts {
|
||||
function getTypeFacts(type: Type, ignoreObjects = false): TypeFacts {
|
||||
const flags = type.flags;
|
||||
if (flags & TypeFlags.String) {
|
||||
return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts;
|
||||
@@ -22002,7 +22002,7 @@ namespace ts {
|
||||
(type === falseType || type === regularFalseType) ? TypeFacts.FalseStrictFacts : TypeFacts.TrueStrictFacts :
|
||||
(type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Object) {
|
||||
if (flags & TypeFlags.Object && !ignoreObjects) {
|
||||
return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(<ObjectType>type) ?
|
||||
strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts :
|
||||
isFunctionObjectType(<ObjectType>type) ?
|
||||
@@ -22025,14 +22025,17 @@ namespace ts {
|
||||
return TypeFacts.None;
|
||||
}
|
||||
if (flags & TypeFlags.Instantiable) {
|
||||
return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType) :
|
||||
return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType, ignoreObjects) :
|
||||
strictNullChecks ? TypeFacts.NonEmptyStringStrictFacts : TypeFacts.NonEmptyStringFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Union) {
|
||||
return reduceLeft((<UnionType>type).types, (facts, t) => facts | getTypeFacts(t), TypeFacts.None);
|
||||
return reduceLeft((<UnionType>type).types, (facts, t) => facts | getTypeFacts(t, ignoreObjects), TypeFacts.None);
|
||||
}
|
||||
if (flags & TypeFlags.Intersection) {
|
||||
return reduceLeft((<UnionType>type).types, (facts, t) => facts & getTypeFacts(t), TypeFacts.All);
|
||||
// When an intersection contains a primitive type we ignore object type constituents as they are
|
||||
// presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type.
|
||||
ignoreObjects ||= maybeTypeOfKind(type, TypeFlags.Primitive);
|
||||
return reduceLeft((<UnionType>type).types, (facts, t) => facts & getTypeFacts(t, ignoreObjects), TypeFacts.All);
|
||||
}
|
||||
return TypeFacts.All;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user