Properly remove generic types that are constrained to 'null | undefined' in getNonNullableType (#44219)

* Improve getNonNullableType function

* Add tests

* More closely match previous behavior

* Add non-strict mode test
This commit is contained in:
Anders Hejlsberg
2021-05-25 11:40:28 -07:00
committed by GitHub
parent 52cefdf79e
commit 3938958d36
9 changed files with 332 additions and 6 deletions

View File

@@ -20325,14 +20325,17 @@ namespace ts {
}
function getGlobalNonNullableTypeInstantiation(type: Type) {
// First reduce away any constituents that are assignable to 'undefined' or 'null'. This not only eliminates
// 'undefined' and 'null', but also higher-order types such as a type parameter 'U extends undefined | null'
// that isn't eliminated by a NonNullable<T> instantiation.
const reducedType = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
if (!deferredGlobalNonNullableTypeAlias) {
deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable" as __String, SymbolFlags.TypeAlias, /*diagnostic*/ undefined) || unknownSymbol;
}
// Use NonNullable global type alias if available to improve quick info/declaration emit
if (deferredGlobalNonNullableTypeAlias !== unknownSymbol) {
return getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [type]);
}
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); // Type alias unavailable, fall back to non-higher-order behavior
// If the NonNullable<T> type is available, return an instantiation. Otherwise just return the reduced type.
return deferredGlobalNonNullableTypeAlias !== unknownSymbol ?
getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [reducedType]) :
reducedType;
}
function getNonNullableType(type: Type): Type {
@@ -24124,7 +24127,7 @@ namespace ts {
}
function isGenericTypeWithUnionConstraint(type: Type) {
return !!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & TypeFlags.Union);
return !!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (TypeFlags.Nullable | TypeFlags.Union));
}
function containsGenericType(type: Type): boolean {