@@ -18292,22 +18292,17 @@ namespace ts {
18292
18292
return Ternary.True;
18293
18293
}
18294
18294
18295
- // Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
18296
- // If so, reporting the `null` and `undefined` in the type is hardly useful.
18297
- // First, see if we're even relating an object type to a union.
18298
- // Then see if the target is stripped down to a single non-union type.
18299
- // Note
18300
- // * We actually want to remove null and undefined naively here (rather than using getNonNullableType),
18301
- // since we don't want to end up with a worse error like "`Foo` is not assignable to `NonNullable<T>`"
18302
- // when dealing with generics.
18303
- // * We also don't deal with primitive source types, since we already halt elaboration below.
18304
- if (target.flags & TypeFlags.Union && source.flags & TypeFlags.Object &&
18305
- (target as UnionType).types.length <= 3 && maybeTypeOfKind(target, TypeFlags.Nullable)) {
18306
- const nullStrippedTarget = extractTypesOfKind(target, ~TypeFlags.Nullable);
18307
- if (!(nullStrippedTarget.flags & (TypeFlags.Union | TypeFlags.Never))) {
18308
- target = getNormalizedType(nullStrippedTarget, /*writing*/ true);
18309
- }
18310
- if (source === nullStrippedTarget) return Ternary.True;
18295
+ // See if we're relating a definitely non-nullable type to a union that includes null and/or undefined
18296
+ // plus a single non-nullable type. If so, remove null and/or undefined from the target type.
18297
+ if (source.flags & TypeFlags.DefinitelyNonNullable && target.flags & TypeFlags.Union) {
18298
+ const types = (target as UnionType).types;
18299
+ const candidate = types.length === 2 && types[0].flags & TypeFlags.Nullable ? types[1] :
18300
+ types.length === 3 && types[0].flags & TypeFlags.Nullable && types[1].flags & TypeFlags.Nullable ? types[2] :
18301
+ undefined;
18302
+ if (candidate && !(candidate.flags & TypeFlags.Nullable)) {
18303
+ target = getNormalizedType(candidate, /*writing*/ true);
18304
+ if (source === target) return Ternary.True;
18305
+ }
18311
18306
}
18312
18307
18313
18308
if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) ||
@@ -18949,8 +18944,6 @@ namespace ts {
18949
18944
return result;
18950
18945
}
18951
18946
if (source.flags & TypeFlags.Intersection || source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.Union) {
18952
- // (T extends 1 | 2) & 1 <=> 1
18953
- // (T extends 1 | 2) <=> T & 1 | T & 2
18954
18947
// The combined constraint of an intersection type is the intersection of the constraints of
18955
18948
// the constituents. When an intersection type contains instantiable types with union type
18956
18949
// constraints, there are situations where we need to examine the combined constraint. One is
0 commit comments