Skip to content

Commit c22a54f

Browse files
committed
Filter out nullable and primitive types in isDiscriminantProperty
1 parent a3845a9 commit c22a54f

1 file changed

Lines changed: 22 additions & 14 deletions

File tree

src/compiler/checker.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ namespace ts {
245245
NEUndefinedOrNull = 1 << 19, // x != undefined / x != null
246246
Truthy = 1 << 20, // x
247247
Falsy = 1 << 21, // !x
248-
All = (1 << 22) - 1,
248+
Discriminatable = 1 << 22, // May have discriminant property
249+
All = (1 << 23) - 1,
249250
// The following members encode facts about particular kinds of types for use in the getTypeFacts function.
250251
// The presence of a particular fact means that the given test is true for some (and possibly all) values
251252
// of that kind of type.
@@ -275,9 +276,9 @@ namespace ts {
275276
TrueFacts = BaseBooleanFacts | Truthy,
276277
SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
277278
SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
278-
ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
279+
ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy | Discriminatable,
279280
ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
280-
FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
281+
FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy | Discriminatable,
281282
FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
282283
UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy,
283284
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
@@ -7848,17 +7849,24 @@ namespace ts {
78487849
}
78497850

78507851
function isDiscriminantProperty(type: Type, name: string) {
7851-
if (type) {
7852-
const nonNullType = getNonNullableType(type);
7853-
if (nonNullType.flags & TypeFlags.Union) {
7854-
const prop = getPropertyOfType(nonNullType, name);
7855-
if (prop && prop.flags & SymbolFlags.SyntheticProperty) {
7856-
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
7857-
(<TransientSymbol>prop).isDiscriminantProperty = !(<TransientSymbol>prop).hasCommonType &&
7858-
isUnitUnionType(getTypeOfSymbol(prop));
7859-
}
7860-
return (<TransientSymbol>prop).isDiscriminantProperty;
7861-
}
7852+
if (type && type.flags & TypeFlags.Union) {
7853+
let prop = getPropertyOfType(type, name);
7854+
if (!prop) {
7855+
// The type may be a union that includes nullable or primtive types. If filtering
7856+
// those out produces a different type, get the property from that type instead.
7857+
// Effectively, we're checking if this *could* be a discriminant property once nullable
7858+
// and primitive types are removed by other type guards.
7859+
const filteredType = getTypeWithFacts(type, TypeFacts.Discriminatable);
7860+
if (filteredType !== type && filteredType.flags & TypeFlags.Union) {
7861+
prop = getPropertyOfType(type, name);
7862+
}
7863+
}
7864+
if (prop && prop.flags & SymbolFlags.SyntheticProperty) {
7865+
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
7866+
(<TransientSymbol>prop).isDiscriminantProperty = !(<TransientSymbol>prop).hasCommonType &&
7867+
isUnitUnionType(getTypeOfSymbol(prop));
7868+
}
7869+
return (<TransientSymbol>prop).isDiscriminantProperty;
78627870
}
78637871
}
78647872
return false;

0 commit comments

Comments
 (0)