@@ -7440,9 +7440,12 @@ namespace ts {
7440
7440
return false;
7441
7441
}
7442
7442
7443
- function isSubtypeOfAny(candidate: Type, types: Type[]): boolean {
7444
- for (const type of types) {
7445
- if (candidate !== type && isTypeSubtypeOf(candidate, type)) {
7443
+ function isSubtypeOfAny(source: Type, targets: Type[]): boolean {
7444
+ for (const target of targets) {
7445
+ if (source !== target && isTypeSubtypeOf(source, target) && (
7446
+ !(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) ||
7447
+ !(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) ||
7448
+ isTypeDerivedFrom(source, target))) {
7446
7449
return true;
7447
7450
}
7448
7451
}
@@ -8565,12 +8568,19 @@ namespace ts {
8565
8568
return isTypeRelatedTo(source, target, assignableRelation);
8566
8569
}
8567
8570
8568
- // A type S is considered to be an instance of a type T if S and T are the same type or if S is a
8569
- // subtype of T but not structurally identical to T. This specifically means that two distinct but
8570
- // structurally identical types (such as two classes) are not considered instances of each other.
8571
- function isTypeInstanceOf(source: Type, target: Type): boolean {
8572
- return getTargetType(source) === getTargetType(target) || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target);
8573
- }
8571
+ // An object type S is considered to be derived from an object type T if
8572
+ // S is a union type and every constituent of S is derived from T,
8573
+ // T is a union type and S is derived from at least one constituent of T, or
8574
+ // T is one of the global types Object and Function and S is a subtype of T, or
8575
+ // T occurs directly or indirectly in an 'extends' clause of S.
8576
+ // Note that this check ignores type parameters and only considers the
8577
+ // inheritance hierarchy.
8578
+ function isTypeDerivedFrom(source: Type, target: Type): boolean {
8579
+ return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
8580
+ target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
8581
+ target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) :
8582
+ hasBaseType(source, getTargetType(target));
8583
+ }
8574
8584
8575
8585
/**
8576
8586
* This is *not* a bi-directional relationship.
@@ -9604,7 +9614,7 @@ namespace ts {
9604
9614
if (relation === identityRelation) {
9605
9615
return propertiesIdenticalTo(source, target);
9606
9616
}
9607
- const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source);
9617
+ const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) ;
9608
9618
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
9609
9619
if (unmatchedProperty) {
9610
9620
if (reportErrors) {
@@ -10312,6 +10322,11 @@ namespace ts {
10312
10322
!(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
10313
10323
}
10314
10324
10325
+ function isEmptyArrayLiteralType(type: Type): boolean {
10326
+ const elementType = isArrayType(type) ? (<TypeReference>type).typeArguments[0] : undefined;
10327
+ return elementType === undefinedWideningType || elementType === neverType;
10328
+ }
10329
+
10315
10330
function isTupleLikeType(type: Type): boolean {
10316
10331
return !!getPropertyOfType(type, "0" as __String);
10317
10332
}
@@ -12415,7 +12430,7 @@ namespace ts {
12415
12430
}
12416
12431
12417
12432
if (targetType) {
12418
- return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf );
12433
+ return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom );
12419
12434
}
12420
12435
12421
12436
return type;
@@ -13883,7 +13898,6 @@ namespace ts {
13883
13898
type.pattern = node;
13884
13899
return type;
13885
13900
}
13886
- const contextualType = getApparentTypeOfContextualType(node);
13887
13901
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
13888
13902
const pattern = contextualType.pattern;
13889
13903
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -18087,14 +18101,6 @@ namespace ts {
18087
18101
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
18088
18102
}
18089
18103
18090
- function getBestChoiceType(type1: Type, type2: Type): Type {
18091
- const firstAssignableToSecond = isTypeAssignableTo(type1, type2);
18092
- const secondAssignableToFirst = isTypeAssignableTo(type2, type1);
18093
- return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
18094
- firstAssignableToSecond && !secondAssignableToFirst ? type2 :
18095
- getUnionType([type1, type2], /*subtypeReduction*/ true);
18096
- }
18097
-
18098
18104
function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) {
18099
18105
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
18100
18106
}
@@ -18231,7 +18237,7 @@ namespace ts {
18231
18237
leftType;
18232
18238
case SyntaxKind.BarBarToken:
18233
18239
return getTypeFacts(leftType) & TypeFacts.Falsy ?
18234
- getBestChoiceType( removeDefinitelyFalsyTypes(leftType), rightType) :
18240
+ getUnionType([ removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true ) :
18235
18241
leftType;
18236
18242
case SyntaxKind.EqualsToken:
18237
18243
checkAssignmentOperator(rightType);
@@ -18391,7 +18397,7 @@ namespace ts {
18391
18397
checkExpression(node.condition);
18392
18398
const type1 = checkExpression(node.whenTrue, checkMode);
18393
18399
const type2 = checkExpression(node.whenFalse, checkMode);
18394
- return getBestChoiceType( type1, type2);
18400
+ return getUnionType([ type1, type2], /*subtypeReduction*/ true );
18395
18401
}
18396
18402
18397
18403
function checkTemplateExpression(node: TemplateExpression): Type {
0 commit comments