Skip to content

Commit 7ae4a21

Browse files
committed
Erase never-like types in several more places
1 parent acd3fec commit 7ae4a21

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

src/compiler/checker.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7121,6 +7121,7 @@ namespace ts {
71217121
let type: Type | undefined;
71227122
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
71237123
if (declaration.dotDotDotToken) {
7124+
parentType = eraseNeverLikeTypes(parentType);
71247125
if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType)) {
71257126
error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types);
71267127
return errorType;
@@ -10250,22 +10251,30 @@ namespace ts {
1025010251
return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined;
1025110252
}
1025210253

10253-
function isNeverLikeIntersection(type: IntersectionType) {
10254-
if (!(type.objectFlags & ObjectFlags.IsNeverIntersectionComputed)) {
10255-
type.objectFlags |= ObjectFlags.IsNeverIntersectionComputed |
10256-
(some(getPropertiesOfUnionOrIntersectionType(type), isDiscriminantWithNeverType) ? ObjectFlags.IsNeverIntersection : 0);
10254+
function eraseNeverLikeTypes(type: Type) {
10255+
return mapType(type, t => isNeverLikeType(t) ? neverType : t);
10256+
}
10257+
10258+
function isNeverLikeType(type: Type) {
10259+
if (type.flags & TypeFlags.Never) {
10260+
return true;
10261+
}
10262+
if (type.flags & TypeFlags.UnionOrIntersection) {
10263+
if (!((<UnionOrIntersectionType>type).objectFlags & ObjectFlags.IsNeverTypeComputed)) {
10264+
const isNeverLike = type.flags & TypeFlags.Union ?
10265+
!((<UnionType>type).objectFlags & ObjectFlags.PrimitiveUnion) && every((<UnionType>type).types, isNeverLikeType) :
10266+
some(getPropertiesOfUnionOrIntersectionType(<IntersectionType>type), isDiscriminantWithNeverType);
10267+
(<UnionOrIntersectionType>type).objectFlags |= ObjectFlags.IsNeverTypeComputed | (isNeverLike ? ObjectFlags.IsNeverType : 0);
10268+
}
10269+
return !!((<UnionOrIntersectionType>type).objectFlags & ObjectFlags.IsNeverType);
1025710270
}
10258-
return !!(type.objectFlags & ObjectFlags.IsNeverIntersection);
10271+
return false;
1025910272
}
1026010273

1026110274
function isDiscriminantWithNeverType(prop: Symbol) {
1026210275
return (getCheckFlags(prop) & (CheckFlags.Discriminant | CheckFlags.HasNeverType)) === CheckFlags.Discriminant && !!(getTypeOfSymbol(prop).flags & TypeFlags.Never);
1026310276
}
1026410277

10265-
function isNeverLikeType(type: Type) {
10266-
return !!(type.flags & TypeFlags.Never || type.flags & TypeFlags.Intersection && isNeverLikeIntersection(<IntersectionType>type));
10267-
}
10268-
1026910278
/**
1027010279
* Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
1027110280
* necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
@@ -10294,7 +10303,7 @@ namespace ts {
1029410303
}
1029510304
return getPropertyOfObjectType(globalObjectType, name);
1029610305
}
10297-
if (type.flags & TypeFlags.Union || type.flags & TypeFlags.Intersection && !isNeverLikeIntersection(<IntersectionType>type)) {
10306+
if (type.flags & TypeFlags.UnionOrIntersection && !isNeverLikeType(type)) {
1029810307
return getPropertyOfUnionOrIntersectionType(<UnionOrIntersectionType>type, name);
1029910308
}
1030010309
return undefined;
@@ -12270,13 +12279,13 @@ namespace ts {
1227012279
}
1227112280

1227212281
function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type {
12273-
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
12282+
return type.flags & TypeFlags.Any || isNeverLikeType(type) ? keyofConstraintType :
12283+
type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
1227412284
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
1227512285
maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
1227612286
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) :
1227712287
type === wildcardType ? wildcardType :
1227812288
type.flags & TypeFlags.Unknown ? neverType :
12279-
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
1228012289
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
1228112290
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
1228212291
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
@@ -13077,6 +13086,7 @@ namespace ts {
1307713086
if (right.flags & TypeFlags.Union) {
1307813087
const merged = tryMergeUnionOfObjectTypeAndEmptyObject(right as UnionType, readonly);
1307913088
if (merged) {
13089+
1308013090
return getSpreadType(left, merged, symbol, objectFlags, readonly);
1308113091
}
1308213092
return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
@@ -13663,6 +13673,9 @@ namespace ts {
1366313673
const mappedTypeVariable = instantiateType(typeVariable, mapper);
1366413674
if (typeVariable !== mappedTypeVariable) {
1366513675
return mapType(mappedTypeVariable, t => {
13676+
if (isNeverLikeType(t)) {
13677+
return neverType;
13678+
}
1366613679
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) {
1366713680
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
1366813681
return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
@@ -14812,7 +14825,7 @@ namespace ts {
1481214825
function getNormalizedType(type: Type, writing: boolean): Type {
1481314826
return isFreshLiteralType(type) ? (<FreshableType>type).regularType :
1481414827
getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).node ? createTypeReference((<TypeReference>type).target, getTypeArguments(<TypeReference>type)) :
14815-
type.flags & TypeFlags.Intersection && isNeverLikeIntersection(<IntersectionType>type) ? neverType :
14828+
type.flags & TypeFlags.UnionOrIntersection && isNeverLikeType(type) ? neverType :
1481614829
type.flags & TypeFlags.Substitution ? writing ? (<SubstitutionType>type).typeVariable : (<SubstitutionType>type).substitute :
1481714830
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
1481814831
type;
@@ -22511,7 +22524,7 @@ namespace ts {
2251122524
hasComputedStringProperty = false;
2251222525
hasComputedNumberProperty = false;
2251322526
}
22514-
const type = checkExpression(memberDecl.expression);
22527+
const type = eraseNeverLikeTypes(checkExpression(memberDecl.expression));
2251522528
if (!isValidSpreadType(type)) {
2251622529
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
2251722530
return errorType;
@@ -22716,7 +22729,7 @@ namespace ts {
2271622729
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
2271722730
attributesTable = createSymbolTable();
2271822731
}
22719-
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
22732+
const exprType = eraseNeverLikeTypes(checkExpressionCached(attributeDecl.expression, checkMode));
2272022733
if (isTypeAny(exprType)) {
2272122734
hasSpreadAnyType = true;
2272222735
}

src/compiler/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4461,9 +4461,9 @@ namespace ts {
44614461
/* @internal */
44624462
IsGenericIndexType = 1 << 25, // Union or intersection contains generic index type
44634463
/* @internal */
4464-
IsNeverIntersectionComputed = 1 << 26,
4464+
IsNeverTypeComputed = 1 << 26,
44654465
/* @internal */
4466-
IsNeverIntersection = 1 << 27,
4466+
IsNeverType = 1 << 27,
44674467
ClassOrInterface = Class | Interface,
44684468
/* @internal */
44694469
RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,

0 commit comments

Comments
 (0)