@@ -3492,8 +3492,8 @@ namespace ts {
3492
3492
context.inferTypeParameters = (<ConditionalType>type).root.inferTypeParameters;
3493
3493
const extendsTypeNode = typeToTypeNodeHelper((<ConditionalType>type).extendsType, context);
3494
3494
context.inferTypeParameters = saveInferTypeParameters;
3495
- const trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType (<ConditionalType>type), context);
3496
- const falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType (<ConditionalType>type), context);
3495
+ const trueTypeNode = typeToTypeNodeHelper((<ConditionalType>type).trueType , context);
3496
+ const falseTypeNode = typeToTypeNodeHelper((<ConditionalType>type).falseType , context);
3497
3497
context.approximateLength += 15;
3498
3498
return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
3499
3499
}
@@ -7477,6 +7477,10 @@ namespace ts {
7477
7477
}
7478
7478
7479
7479
function getConstraintOfIndexedAccess(type: IndexedAccessType) {
7480
+ return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined;
7481
+ }
7482
+
7483
+ function getConstraintFromIndexedAccess(type: IndexedAccessType) {
7480
7484
const objectType = getConstraintOfType(type.objectType) || type.objectType;
7481
7485
if (objectType !== type.objectType) {
7482
7486
const constraint = getIndexedAccessType(objectType, type.indexType, /*accessNode*/ undefined, errorType);
@@ -7488,24 +7492,14 @@ namespace ts {
7488
7492
return baseConstraint && baseConstraint !== type ? baseConstraint : undefined;
7489
7493
}
7490
7494
7491
- function getDefaultConstraintOfTrueBranchOfConditionalType(root: ConditionalRoot, combinedMapper: TypeMapper | undefined, mapper: TypeMapper | undefined) {
7492
- const rootTrueType = root.trueType;
7493
- const rootTrueConstraint = !(rootTrueType.flags & TypeFlags.Substitution)
7494
- ? rootTrueType
7495
- : instantiateType(((<SubstitutionType>rootTrueType).substitute), combinedMapper || mapper).flags & TypeFlags.AnyOrUnknown
7496
- ? (<SubstitutionType>rootTrueType).typeVariable
7497
- : getIntersectionType([(<SubstitutionType>rootTrueType).substitute, (<SubstitutionType>rootTrueType).typeVariable]);
7498
- return instantiateType(rootTrueConstraint, combinedMapper || mapper);
7499
- }
7500
-
7501
7495
function getDefaultConstraintOfConditionalType(type: ConditionalType) {
7502
7496
if (!type.resolvedDefaultConstraint) {
7503
7497
// An `any` branch of a conditional type would normally be viral - specifically, without special handling here,
7504
7498
// a conditional type with a single branch of type `any` would be assignable to anything, since it's constraint would simplify to
7505
7499
// just `any`. This result is _usually_ unwanted - so instead here we elide an `any` branch from the constraint type,
7506
7500
// in effect treating `any` like `never` rather than `unknown` in this location.
7507
- const trueConstraint = getDefaultConstraintOfTrueBranchOfConditionalType (type.root, type.combinedMapper, type.mapper );
7508
- const falseConstraint = getFalseTypeFromConditionalType( type) ;
7501
+ const trueConstraint = getInferredTrueTypeFromConditionalType (type);
7502
+ const falseConstraint = type.falseType ;
7509
7503
type.resolvedDefaultConstraint = isTypeAny(trueConstraint) ? falseConstraint : isTypeAny(falseConstraint) ? trueConstraint : getUnionType([trueConstraint, falseConstraint]);
7510
7504
}
7511
7505
return type.resolvedDefaultConstraint;
@@ -7537,10 +7531,14 @@ namespace ts {
7537
7531
return undefined;
7538
7532
}
7539
7533
7540
- function getConstraintOfConditionalType (type: ConditionalType) {
7534
+ function getConstraintFromConditionalType (type: ConditionalType) {
7541
7535
return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
7542
7536
}
7543
7537
7538
+ function getConstraintOfConditionalType(type: ConditionalType) {
7539
+ return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined;
7540
+ }
7541
+
7544
7542
function getUnionConstraintOfIntersection(type: IntersectionType, targetIsUnion: boolean) {
7545
7543
let constraints: Type[] | undefined;
7546
7544
let hasDisjointDomainType = false;
@@ -7617,7 +7615,7 @@ namespace ts {
7617
7615
if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
7618
7616
return circularConstraintType;
7619
7617
}
7620
- if (constraintDepth == = 50) {
7618
+ if (constraintDepth > = 50) {
7621
7619
// We have reached 50 recursive invocations of getImmediateBaseConstraint and there is a
7622
7620
// very high likelyhood we're dealing with an infinite generic type that perpetually generates
7623
7621
// new type identities as we descend into it. We stop the recursion here and mark this type
@@ -7684,8 +7682,11 @@ namespace ts {
7684
7682
return baseIndexedAccess && baseIndexedAccess !== errorType ? getBaseConstraint(baseIndexedAccess) : undefined;
7685
7683
}
7686
7684
if (t.flags & TypeFlags.Conditional) {
7687
- const constraint = getConstraintOfConditionalType(<ConditionalType>t);
7688
- return constraint && getBaseConstraint(constraint);
7685
+ const constraint = getConstraintFromConditionalType(<ConditionalType>t);
7686
+ constraintDepth++; // Penalize repeating conditional types (this captures the recursion within getConstraintFromConditionalType and carries it forward)
7687
+ const result = constraint && getBaseConstraint(constraint);
7688
+ constraintDepth--;
7689
+ return result;
7689
7690
}
7690
7691
if (t.flags & TypeFlags.Substitution) {
7691
7692
return getBaseConstraint((<SubstitutionType>t).substitute);
@@ -8866,6 +8867,9 @@ namespace ts {
8866
8867
}
8867
8868
8868
8869
function getSubstitutionType(typeVariable: TypeVariable, substitute: Type) {
8870
+ if (substitute.flags & TypeFlags.AnyOrUnknown) {
8871
+ return typeVariable;
8872
+ }
8869
8873
const result = <SubstitutionType>createType(TypeFlags.Substitution);
8870
8874
result.typeVariable = typeVariable;
8871
8875
result.substitute = substitute;
@@ -10161,7 +10165,7 @@ namespace ts {
10161
10165
// Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
10162
10166
if (falseType.flags & TypeFlags.Never && isTypeIdenticalTo(getActualTypeVariable(trueType), getActualTypeVariable(checkType))) {
10163
10167
if (checkType.flags & TypeFlags.Any || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
10164
- return getDefaultConstraintOfTrueBranchOfConditionalType(root, /*combinedMapper*/ undefined, mapper) ;
10168
+ return trueType ;
10165
10169
}
10166
10170
else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
10167
10171
return neverType;
@@ -10172,7 +10176,7 @@ namespace ts {
10172
10176
return neverType;
10173
10177
}
10174
10178
else if (checkType.flags & TypeFlags.Any || isIntersectionEmpty(checkType, extendsType)) { // Always false
10175
- return falseType; // TODO: Intersect negated `extends` type here
10179
+ return falseType;
10176
10180
}
10177
10181
}
10178
10182
@@ -10227,21 +10231,15 @@ namespace ts {
10227
10231
result.extendsType = extendsType;
10228
10232
result.mapper = mapper;
10229
10233
result.combinedMapper = combinedMapper;
10230
- if (!combinedMapper) {
10231
- result.resolvedTrueType = trueType;
10232
- result.resolvedFalseType = falseType;
10233
- }
10234
+ result.trueType = trueType;
10235
+ result.falseType = falseType;
10234
10236
result.aliasSymbol = root.aliasSymbol;
10235
10237
result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper!); // TODO: GH#18217
10236
10238
return result;
10237
10239
}
10238
10240
10239
- function getTrueTypeFromConditionalType(type: ConditionalType) {
10240
- return type.resolvedTrueType || (type.resolvedTrueType = instantiateType(type.root.trueType, type.mapper));
10241
- }
10242
-
10243
- function getFalseTypeFromConditionalType(type: ConditionalType) {
10244
- return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper));
10241
+ function getInferredTrueTypeFromConditionalType(type: ConditionalType) {
10242
+ return type.resolvedInferredTrueType || (type.resolvedInferredTrueType = instantiateType(type.root.trueType, type.combinedMapper || type.mapper));
10245
10243
}
10246
10244
10247
10245
function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] | undefined {
@@ -11182,7 +11180,11 @@ namespace ts {
11182
11180
return getSubstitutionType(maybeVariable as TypeVariable, instantiateType((<SubstitutionType>type).substitute, mapper));
11183
11181
}
11184
11182
else {
11185
- return maybeVariable;
11183
+ const sub = instantiateType((<SubstitutionType>type).substitute, mapper);
11184
+ if (sub.flags & TypeFlags.AnyOrUnknown || isTypeSubtypeOf(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) {
11185
+ return maybeVariable;
11186
+ }
11187
+ return sub;
11186
11188
}
11187
11189
}
11188
11190
return type;
@@ -11727,6 +11729,15 @@ namespace ts {
11727
11729
11728
11730
type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void;
11729
11731
11732
+ /**
11733
+ * Returns true if `s` is `(...args: any[]) => any` or `(this: any, ...args: any[]) => any`
11734
+ */
11735
+ function isAnySignature(s: Signature) {
11736
+ return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
11737
+ s.hasRestParameter && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
11738
+ isTypeAny(getReturnTypeOfSignature(s));
11739
+ }
11740
+
11730
11741
/**
11731
11742
* See signatureRelatedTo, compareSignaturesIdentical
11732
11743
*/
@@ -11742,6 +11753,10 @@ namespace ts {
11742
11753
return Ternary.True;
11743
11754
}
11744
11755
11756
+ if (isAnySignature(target)) {
11757
+ return Ternary.True;
11758
+ }
11759
+
11745
11760
const targetCount = getParameterCount(target);
11746
11761
if (!hasEffectiveRestParameter(target) && getMinArgumentCount(source) > targetCount) {
11747
11762
return Ternary.False;
@@ -12706,8 +12721,8 @@ namespace ts {
12706
12721
if ((<ConditionalType>source).root.isDistributive === (<ConditionalType>target).root.isDistributive) {
12707
12722
if (result = isRelatedTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType, /*reportErrors*/ false)) {
12708
12723
if (result &= isRelatedTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType, /*reportErrors*/ false)) {
12709
- if (result &= isRelatedTo(getTrueTypeFromConditionalType (<ConditionalType>source), getTrueTypeFromConditionalType (<ConditionalType>target), /*reportErrors*/ false)) {
12710
- if (result &= isRelatedTo(getFalseTypeFromConditionalType (<ConditionalType>source), getFalseTypeFromConditionalType (<ConditionalType>target), /*reportErrors*/ false)) {
12724
+ if (result &= isRelatedTo((<ConditionalType>source).trueType, (<ConditionalType>target).trueType , /*reportErrors*/ false)) {
12725
+ if (result &= isRelatedTo((<ConditionalType>source).falseType, (<ConditionalType>target).falseType , /*reportErrors*/ false)) {
12711
12726
return result;
12712
12727
}
12713
12728
}
@@ -12828,7 +12843,7 @@ namespace ts {
12828
12843
return result;
12829
12844
}
12830
12845
}
12831
- const constraint = getConstraintOfType(<TypeParameter >source);
12846
+ const constraint = getConstraintOfType(<TypeVariable >source);
12832
12847
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
12833
12848
// A type variable with no constraint is not related to the non-primitive object type.
12834
12849
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
@@ -12860,8 +12875,8 @@ namespace ts {
12860
12875
// and Y1 is related to Y2.
12861
12876
if (isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType) &&
12862
12877
(isRelatedTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType) || isRelatedTo((<ConditionalType>target).checkType, (<ConditionalType>source).checkType))) {
12863
- if (result = isRelatedTo(getTrueTypeFromConditionalType (<ConditionalType>source), getTrueTypeFromConditionalType (<ConditionalType>target), reportErrors)) {
12864
- result &= isRelatedTo(getFalseTypeFromConditionalType (<ConditionalType>source), getFalseTypeFromConditionalType (<ConditionalType>target), reportErrors);
12878
+ if (result = isRelatedTo((<ConditionalType>source).trueType, (<ConditionalType>target).trueType , reportErrors)) {
12879
+ result &= isRelatedTo((<ConditionalType>source).falseType, (<ConditionalType>target).falseType , reportErrors);
12865
12880
}
12866
12881
if (result) {
12867
12882
errorInfo = saveErrorInfo;
@@ -14696,12 +14711,12 @@ namespace ts {
14696
14711
else if (source.flags & TypeFlags.Conditional && target.flags & TypeFlags.Conditional) {
14697
14712
inferFromTypes((<ConditionalType>source).checkType, (<ConditionalType>target).checkType);
14698
14713
inferFromTypes((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType);
14699
- inferFromTypes(getTrueTypeFromConditionalType (<ConditionalType>source), getTrueTypeFromConditionalType (<ConditionalType>target));
14700
- inferFromTypes(getFalseTypeFromConditionalType (<ConditionalType>source), getFalseTypeFromConditionalType (<ConditionalType>target));
14714
+ inferFromTypes((<ConditionalType>source).trueType, (<ConditionalType>target).trueType );
14715
+ inferFromTypes((<ConditionalType>source).falseType, (<ConditionalType>target).falseType );
14701
14716
}
14702
14717
else if (target.flags & TypeFlags.Conditional && !contravariant) {
14703
- inferFromTypes(source, getTrueTypeFromConditionalType (<ConditionalType>target));
14704
- inferFromTypes(source, getFalseTypeFromConditionalType (<ConditionalType>target));
14718
+ inferFromTypes(source, (<ConditionalType>target).trueType );
14719
+ inferFromTypes(source, (<ConditionalType>target).falseType );
14705
14720
}
14706
14721
else if (target.flags & TypeFlags.UnionOrIntersection) {
14707
14722
for (const t of (<UnionOrIntersectionType>target).types) {
0 commit comments