diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a74e5269cdba..f07c6f0f36727 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -197,6 +197,13 @@ namespace ts { InPropertyCheck = 1 << 4, } + const enum RecursionFlags { + None = 0, + Source = 1 << 0, + Target = 1 << 1, + Both = Source | Target, + } + const enum MappedTypeModifiers { IncludeReadonly = 1 << 0, ExcludeReadonly = 1 << 1, @@ -17747,7 +17754,8 @@ namespace ts { let sourceStack: Type[]; let targetStack: Type[]; let maybeCount = 0; - let depth = 0; + let sourceDepth = 0; + let targetDepth = 0; let expandingFlags = ExpandingFlags.None; let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid @@ -17757,12 +17765,12 @@ namespace ts { Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); - const result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage); + const result = isRelatedTo(source, target, RecursionFlags.Both, /*reportErrors*/ !!errorNode, headMessage); if (incompatibleStack.length) { reportIncompatibleStack(); } if (overflow) { - tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth }); + tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth: sourceDepth, targetDepth }); const diag = error(errorNode || currentNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); if (errorOutputContainer) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); @@ -18067,13 +18075,17 @@ namespace ts { return true; } + function isRelatedToWorker(source: Type, target: Type, reportErrors: boolean) { + return isRelatedTo(source, target, RecursionFlags.Both, reportErrors); + } + /** * Compare two types and return * * Ternary.True if they are related with no assumptions, * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ - function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { @@ -18094,7 +18106,7 @@ namespace ts { if (source === target) return Ternary.True; if (relation === identityRelation) { - return isIdenticalTo(source, target); + return isIdenticalTo(source, target, recursionFlags); } // We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common, @@ -18148,8 +18160,8 @@ namespace ts { const targetString = typeToString(originalTarget.aliasSymbol ? originalTarget : target); const calls = getSignaturesOfType(source, SignatureKind.Call); const constructs = getSignaturesOfType(source, SignatureKind.Construct); - if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) || - constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) { + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, RecursionFlags.Source, /*reportErrors*/ false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, RecursionFlags.Source, /*reportErrors*/ false)) { reportError(Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString); } else { @@ -18169,11 +18181,11 @@ namespace ts { // and we need to handle "each" relations before "some" relations for the same kind of type. if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) { result = getConstituentCount(source) * getConstituentCount(target) >= 4 ? - recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck) : + recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags) : structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck); } if (!result && !(source.flags & TypeFlags.Union) && (source.flags & (TypeFlags.StructuredOrInstantiable) || target.flags & TypeFlags.StructuredOrInstantiable)) { - if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) { + if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags)) { resetErrorInfo(saveErrorInfo); } } @@ -18195,7 +18207,7 @@ namespace ts { if (constraint && (source.flags & TypeFlags.Intersection || target.flags & TypeFlags.Union)) { if (everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this - if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); } } @@ -18221,7 +18233,7 @@ namespace ts { target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) || isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) { inPropertyCheck = true; - result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck); + result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags); inPropertyCheck = false; } @@ -18303,7 +18315,7 @@ namespace ts { } } - function isIdenticalTo(source: Type, target: Type): Ternary { + function isIdenticalTo(source: Type, target: Type, recursionFlags: RecursionFlags): Ternary { if (source.flags !== target.flags) return Ternary.False; if (source.flags & TypeFlags.Singleton) return Ternary.True; traceUnionsOrIntersectionsTooLarge(source, target); @@ -18314,7 +18326,7 @@ namespace ts { } return result; } - return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, IntersectionState.None); + return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, IntersectionState.None, recursionFlags); } function getTypeOfPropertyInTypes(types: Type[], name: __String) { @@ -18398,7 +18410,7 @@ namespace ts { } return true; } - if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), reportErrors)) { + if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), RecursionFlags.Both, reportErrors)) { if (reportErrors) { reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop)); } @@ -18434,21 +18446,21 @@ namespace ts { } const match = getMatchingUnionConstituentForType(target as UnionType, source); if (match) { - const related = isRelatedTo(source, match, /*reportErrors*/ false); + const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false); if (related) { return related; } } } for (const type of targetTypes) { - const related = isRelatedTo(source, type, /*reportErrors*/ false); + const related = isRelatedTo(source, type, RecursionFlags.Target, /*reportErrors*/ false); if (related) { return related; } } if (reportErrors) { const bestMatchingType = getBestMatchingType(source, target, isRelatedTo); - isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); + isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], RecursionFlags.Target, /*reportErrors*/ true); } return Ternary.False; } @@ -18457,7 +18469,7 @@ namespace ts { let result = Ternary.True; const targetTypes = target.types; for (const targetType of targetTypes) { - const related = isRelatedTo(source, targetType, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(source, targetType, RecursionFlags.Target, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { return Ternary.False; } @@ -18473,7 +18485,7 @@ namespace ts { } const len = sourceTypes.length; for (let i = 0; i < len; i++) { - const related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceTypes[i], target, RecursionFlags.Source, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState); if (related) { return related; } @@ -18505,13 +18517,13 @@ namespace ts { // union has a union of objects intersected with it. In such cases, if the input was, eg `("a" | "b" | "c") & (string | boolean | {} | {whatever})`, // the result will have the structure `"a" | "b" | "c" | "a" & {} | "b" & {} | "c" & {} | "a" & {whatever} | "b" & {whatever} | "c" & {whatever}` // - the resulting union has a length which is a multiple of the original union, and the elements correspond modulo the length of the original union - const related = isRelatedTo(sourceType, (undefinedStrippedTarget as UnionType).types[i % (undefinedStrippedTarget as UnionType).types.length], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, (undefinedStrippedTarget as UnionType).types[i % (undefinedStrippedTarget as UnionType).types.length], RecursionFlags.Both, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (related) { result &= related; continue; } } - const related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, target, RecursionFlags.Source, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { return Ternary.False; } @@ -18541,31 +18553,31 @@ namespace ts { // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_. // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be) - related = relation === identityRelation ? isRelatedTo(s, t, /*reportErrors*/ false) : compareTypesIdentical(s, t); + related = relation === identityRelation ? isRelatedTo(s, t, RecursionFlags.Both, /*reportErrors*/ false) : compareTypesIdentical(s, t); } else if (variance === VarianceFlags.Covariant) { - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } else if (variance === VarianceFlags.Contravariant) { - related = isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(t, s, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } else if (variance === VarianceFlags.Bivariant) { // In the bivariant case we first compare contravariantly without reporting // errors. Then, if that doesn't succeed, we compare covariantly with error // reporting. Thus, error elaboration will be based on the the covariant check, // which is generally easier to reason about. - related = isRelatedTo(t, s, /*reportErrors*/ false); + related = isRelatedTo(t, s, RecursionFlags.Both, /*reportErrors*/ false); if (!related) { - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } } else { // In the invariant case we first compare covariantly, and only when that // succeeds do we proceed to compare contravariantly. Thus, error elaboration // will typically be based on the covariant check. - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (related) { - related &= isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState); + related &= isRelatedTo(t, s, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } } if (!related) { @@ -18582,7 +18594,7 @@ namespace ts { // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion // and issue an error. Otherwise, actually compare the structure of the two types. - function recursiveTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function recursiveTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, recursionFlags: RecursionFlags): Ternary { if (overflow) { return Ternary.False; } @@ -18626,7 +18638,7 @@ namespace ts { return Ternary.Maybe; } } - if (depth === 100) { + if (sourceDepth === 100 || targetDepth === 100) { overflow = true; return Ternary.False; } @@ -18634,12 +18646,17 @@ namespace ts { const maybeStart = maybeCount; maybeKeys[maybeCount] = id; maybeCount++; - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; + if (recursionFlags & RecursionFlags.Source) { + sourceStack[sourceDepth] = source; + sourceDepth++; + } + if (recursionFlags & RecursionFlags.Target) { + targetStack[targetDepth] = target; + targetDepth++; + } const saveExpandingFlags = expandingFlags; - if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= ExpandingFlags.Source; - if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= ExpandingFlags.Target; + if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source; + if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target; let originalHandler: typeof outofbandVarianceMarkerHandler; let propagatingVarianceFlags: RelationComparisonResult = 0; if (outofbandVarianceMarkerHandler) { @@ -18656,7 +18673,8 @@ namespace ts { sourceIdStack: sourceStack.map(t => t.id), targetId: target.id, targetIdStack: targetStack.map(t => t.id), - depth, + depth: sourceDepth, + targetDepth }); } @@ -18665,9 +18683,14 @@ namespace ts { outofbandVarianceMarkerHandler = originalHandler; } expandingFlags = saveExpandingFlags; - depth--; + if (recursionFlags & RecursionFlags.Source) { + sourceDepth--; + } + if (recursionFlags & RecursionFlags.Target) { + targetDepth--; + } if (result) { - if (result === Ternary.True || depth === 0) { + if (result === Ternary.True || (sourceDepth === 0 && targetDepth === 0)) { if (result === Ternary.True || result === Ternary.Maybe) { // If result is definitely true, record all maybe keys as having succeeded. Also, record Ternary.Maybe // results as having succeeded once we reach depth 0, but never record Ternary.Unknown results. @@ -18723,7 +18746,7 @@ namespace ts { if (constraints !== (source as IntersectionType).types) { source = getIntersectionType(constraints); if (!(source.flags & TypeFlags.Intersection)) { - return isRelatedTo(source, target, /*reportErrors*/ false); + return isRelatedTo(source, target, RecursionFlags.Source, /*reportErrors*/ false); } } } @@ -18745,22 +18768,22 @@ namespace ts { const flags = source.flags & target.flags; if (relation === identityRelation && !(flags & TypeFlags.Object)) { if (flags & TypeFlags.Index) { - return isRelatedTo((source as IndexType).type, (target as IndexType).type, /*reportErrors*/ false); + return isRelatedTo((source as IndexType).type, (target as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false); } let result = Ternary.False; if (flags & TypeFlags.IndexedAccess) { - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, /*reportErrors*/ false)) { + if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } } if (flags & TypeFlags.Conditional) { if ((source as ConditionalType).root.isDistributive === (target as ConditionalType).root.isDistributive) { - if (result = isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as ConditionalType).extendsType, (target as ConditionalType).extendsType, /*reportErrors*/ false)) { - if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target as ConditionalType), /*reportErrors*/ false)) { - if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), /*reportErrors*/ false)) { + if (result = isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as ConditionalType).extendsType, (target as ConditionalType).extendsType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } @@ -18769,7 +18792,7 @@ namespace ts { } } if (flags & TypeFlags.Substitution) { - return isRelatedTo((source as SubstitutionType).substitute, (target as SubstitutionType).substitute, /*reportErrors*/ false); + return isRelatedTo((source as SubstitutionType).substitute, (target as SubstitutionType).substitute, RecursionFlags.Both, /*reportErrors*/ false); } return Ternary.False; } @@ -18797,19 +18820,19 @@ namespace ts { // For a generic type T and a type U that is assignable to T, [...U] is assignable to T, U is assignable to readonly [...T], // and U is assignable to [...T] when U is constrained to a mutable array or tuple type. - if (isSingleElementGenericTupleType(source) && !source.target.readonly && (result = isRelatedTo(getTypeArguments(source)[0], target)) || - isSingleElementGenericTupleType(target) && (target.target.readonly || isMutableArrayOrTuple(getBaseConstraintOfType(source) || source)) && (result = isRelatedTo(source, getTypeArguments(target)[0]))) { + if (isSingleElementGenericTupleType(source) && !source.target.readonly && (result = isRelatedTo(getTypeArguments(source)[0], target, RecursionFlags.Source)) || + isSingleElementGenericTupleType(target) && (target.target.readonly || isMutableArrayOrTuple(getBaseConstraintOfType(source) || source)) && (result = isRelatedTo(source, getTypeArguments(target)[0], RecursionFlags.Target))) { return result; } if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. - if (getObjectFlags(source) & ObjectFlags.Mapped && !(source as MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as MappedType))) { + if (getObjectFlags(source) & ObjectFlags.Mapped && !(source as MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as MappedType), RecursionFlags.Both)) { if (!(getMappedTypeModifiers(source as MappedType) & MappedTypeModifiers.IncludeOptional)) { const templateType = getTemplateTypeFromMappedType(source as MappedType); const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source as MappedType)); - if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) { + if (result = isRelatedTo(templateType, indexedAccessType, RecursionFlags.Both, reportErrors)) { return result; } } @@ -18819,14 +18842,14 @@ namespace ts { const targetType = (target as IndexType).type; // A keyof S is related to a keyof T if T is related to S. if (source.flags & TypeFlags.Index) { - if (result = isRelatedTo(targetType, (source as IndexType).type, /*reportErrors*/ false)) { + if (result = isRelatedTo(targetType, (source as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } if (isTupleType(targetType)) { // An index type can have a tuple type target when the tuple type contains variadic elements. // Check if the source is related to the known keys of the tuple type. - if (result = isRelatedTo(source, getKnownKeysOfTupleType(targetType), reportErrors)) { + if (result = isRelatedTo(source, getKnownKeysOfTupleType(targetType), RecursionFlags.Target, reportErrors)) { return result; } } @@ -18839,7 +18862,7 @@ namespace ts { // false positives. For example, given 'T extends { [K in keyof T]: string }', // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when // related to other types. - if (isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors) === Ternary.True) { + if (isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), RecursionFlags.Target, reportErrors) === Ternary.True) { return Ternary.True; } } @@ -18868,7 +18891,7 @@ namespace ts { else { targetKeys = nameType || constraintType; } - if (isRelatedTo(source, targetKeys, reportErrors) === Ternary.True) { + if (isRelatedTo(source, targetKeys, RecursionFlags.Target, reportErrors) === Ternary.True) { return Ternary.True; } } @@ -18878,8 +18901,8 @@ namespace ts { if (source.flags & TypeFlags.IndexedAccess) { // Relate components directly before falling back to constraint relationships // A type S[K] is related to a type T[J] if S is related to T and K is related to J. - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, reportErrors)) { - result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, reportErrors); + if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors); } if (result) { resetErrorInfo(saveErrorInfo); @@ -18904,7 +18927,7 @@ namespace ts { // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, reportErrors)) { + if (result = isRelatedTo(source, constraint, RecursionFlags.Target, reportErrors)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -18944,14 +18967,15 @@ namespace ts { // A source type `S` is related to a target type `{ [P in Q as R]?: T }` if some constituent `R'` of `R` is related to `keyof S` and `S[R']` is related to `T`. if (includeOptional ? !(filteredByApplicability!.flags & TypeFlags.Never) - : isRelatedTo(targetKeys, sourceKeys)) { + : isRelatedTo(targetKeys, sourceKeys, RecursionFlags.Both)) { + const templateType = getTemplateTypeFromMappedType(target); const typeParameter = getTypeParameterFromMappedType(target); // Fastpath: When the template type has the form `Obj[P]` where `P` is the mapped type parameter, directly compare source `S` with `Obj` // to avoid creating the (potentially very large) number of new intermediate types made by manufacturing `S[P]`. const nonNullComponent = extractTypesOfKind(templateType, ~TypeFlags.Nullable); if (!keysRemapped && nonNullComponent.flags & TypeFlags.IndexedAccess && (nonNullComponent as IndexedAccessType).indexType === typeParameter) { - if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, reportErrors)) { + if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, RecursionFlags.Target, reportErrors)) { return result; } } @@ -18972,7 +18996,7 @@ namespace ts { : typeParameter; const indexedAccessType = getIndexedAccessType(source, indexingType); // Compare `S[indexingType]` to `T`, where `T` is the type of a property of the target type. - if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { + if (result = isRelatedTo(indexedAccessType, templateType, RecursionFlags.Both, reportErrors)) { return result; } } @@ -19001,10 +19025,11 @@ namespace ts { } // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - let localResult: Ternary | undefined; - if (skipTrue || (localResult = isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.trueType), distributionMapper) : getTrueTypeFromConditionalType(c), /*reportErrors*/ false))) { - if (!skipFalse) { - localResult = (localResult || Ternary.Maybe) & isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.falseType), distributionMapper) : getFalseTypeFromConditionalType(c), /*reportErrors*/ false); + const expanding = isDeeplyNestedType(target, targetStack, targetDepth); + let localResult: Ternary | undefined = expanding ? Ternary.Maybe : undefined; + if (skipTrue || expanding || (localResult = isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.trueType), distributionMapper) : getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false))) { + if (!skipFalse && !expanding) { + localResult = (localResult || Ternary.Maybe) & isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.falseType), distributionMapper) : getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); } } if (localResult) { @@ -19033,25 +19058,25 @@ namespace ts { const constraint = getConstraintOfType(source as TypeVariable); if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { // A type variable with no constraint is not related to the non-primitive object type. - if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive), RecursionFlags.Both)) { resetErrorInfo(saveErrorInfo); return result; } } // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed - else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors && !(target.flags & source.flags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(target.flags & source.flags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } } } else if (source.flags & TypeFlags.Index) { - if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) { + if (result = isRelatedTo(keyofConstraintType, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } @@ -19059,7 +19084,7 @@ namespace ts { else if (source.flags & TypeFlags.TemplateLiteral && !(target.flags & TypeFlags.Object)) { if (!(target.flags & TypeFlags.TemplateLiteral)) { const constraint = getBaseConstraintOfType(source); - if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, reportErrors))) { + if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) { resetErrorInfo(saveErrorInfo); return result; } @@ -19067,14 +19092,14 @@ namespace ts { } else if (source.flags & TypeFlags.StringMapping) { if (target.flags & TypeFlags.StringMapping && (source as StringMappingType).symbol === (target as StringMappingType).symbol) { - if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, reportErrors)) { + if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } else { const constraint = getBaseConstraintOfType(source); - if (constraint && (result = isRelatedTo(constraint, target, reportErrors))) { + if (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) { resetErrorInfo(saveErrorInfo); return result; } @@ -19082,27 +19107,32 @@ namespace ts { } else if (source.flags & TypeFlags.Conditional) { if (target.flags & TypeFlags.Conditional) { - // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if - // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, - // and Y1 is related to Y2. - const sourceParams = (source as ConditionalType).root.inferTypeParameters; - let sourceExtends = (source as ConditionalType).extendsType; - let mapper: TypeMapper | undefined; - if (sourceParams) { - // If the source has infer type parameters, we instantiate them in the context of the target - const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedTo); - inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); - sourceExtends = instantiateType(sourceExtends, ctx.mapper); - mapper = ctx.mapper; - } - if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && - (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType))) { - if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), reportErrors)) { - result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), reportErrors); - } - if (result) { - resetErrorInfo(saveErrorInfo); - return result; + // If one of the conditionals under comparison seems to be infinitely expanding, stop comparing it - back out, try + // the constraint, and failing that, give up trying to relate the two. This is the only way we can handle recursive conditional + // types, which might expand forever. + if (!isDeeplyNestedType(source, sourceStack, sourceDepth) && !isDeeplyNestedType(target, targetStack, targetDepth)) { + // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if + // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, + // and Y1 is related to Y2. + const sourceParams = (source as ConditionalType).root.inferTypeParameters; + let sourceExtends = (source as ConditionalType).extendsType; + let mapper: TypeMapper | undefined; + if (sourceParams) { + // If the source has infer type parameters, we instantiate them in the context of the target + const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedToWorker); + inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + sourceExtends = instantiateType(sourceExtends, ctx.mapper); + mapper = ctx.mapper; + } + if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && + (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType, RecursionFlags.Both))) { + if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors); + } + if (result) { + resetErrorInfo(saveErrorInfo); + return result; + } } } } @@ -19111,19 +19141,25 @@ namespace ts { // more assignments than are desirable (since it maps the source check type to its constraint, it loses information) const distributiveConstraint = getConstraintOfDistributiveConditionalType(source as ConditionalType); if (distributiveConstraint) { - if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) { + if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } } - // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` - // when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!). - const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); - if (defaultConstraint) { - if (result = isRelatedTo(defaultConstraint, target, reportErrors)) { - resetErrorInfo(saveErrorInfo); - return result; + + + // We'll repeatedly decompose source side conditionals if they're recursive - check if we've already recured on the constraint a lot and, if so, bail + // on the comparison. + if (!isDeeplyNestedType(source, sourceStack, sourceDepth)) { + // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` + // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). + const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); + if (defaultConstraint) { + if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) { + resetErrorInfo(saveErrorInfo); + return result; + } } } } @@ -19167,7 +19203,7 @@ namespace ts { } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { if (relation !== identityRelation) { - return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, reportErrors); + return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors); } else { // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple @@ -19293,10 +19329,10 @@ namespace ts { let result: Ternary; const targetConstraint = getConstraintTypeFromMappedType(target); const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers)); - if (result = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) { + if (result = isRelatedTo(targetConstraint, sourceConstraint, RecursionFlags.Both, reportErrors)) { const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]); if (instantiateType(getNameTypeFromMappedType(source), mapper) === instantiateType(getNameTypeFromMappedType(target), mapper)) { - return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors); + return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), RecursionFlags.Both, reportErrors); } } } @@ -19418,7 +19454,7 @@ namespace ts { const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ false, targetIsOptional); const effectiveSource = getTypeOfSourceProperty(sourceProp); - return isRelatedTo(effectiveSource, effectiveTarget, reportErrors, /*headMessage*/ undefined, intersectionState); + return isRelatedTo(effectiveSource, effectiveTarget, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState, skipOptional: boolean): Ternary { @@ -19612,7 +19648,7 @@ namespace ts { const targetType = targetTypeArguments[i]; const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); - const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors && (targetArity > 1 || sourceArity > 1)) { if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { @@ -19812,7 +19848,7 @@ namespace ts { */ function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary { return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, - relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, makeFunctionTypeMapper(reportUnreliableMarkers)); + relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedToWorker, makeFunctionTypeMapper(reportUnreliableMarkers)); } function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary { @@ -19846,7 +19882,7 @@ namespace ts { const type = exactOptionalPropertyTypes || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); - const related = isRelatedTo(type, targetInfo.type, reportErrors); + const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related) { if (reportErrors) { reportError(Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); @@ -19869,7 +19905,7 @@ namespace ts { } function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean) { - const related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); + const related = isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related && reportErrors) { if (sourceInfo.keyType === targetInfo.keyType) { reportError(Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType)); @@ -19890,7 +19926,7 @@ namespace ts { let result = Ternary.True; for (const targetInfo of indexInfos) { const related = !sourceIsPrimitive && targetHasStringIndex && targetInfo.type.flags & TypeFlags.Any ? Ternary.True : - isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors) : + isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, RecursionFlags.Both, reportErrors) : typeRelatedToIndexInfo(source, targetInfo, reportErrors, intersectionState); if (!related) { return Ternary.False; @@ -19923,7 +19959,7 @@ namespace ts { } for (const targetInfo of targetInfos) { const sourceInfo = getIndexInfoOfType(source, targetInfo.keyType); - if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type) && sourceInfo.isReadonly === targetInfo.isReadonly)) { + if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both) && sourceInfo.isReadonly === targetInfo.isReadonly)) { return Ternary.False; } } @@ -24456,16 +24492,7 @@ namespace ts { function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, isRelated: (source: Type, target: Type) => boolean) { if (!assumeTrue) { - return filterType(type, t => { - if (!isRelated(t, candidate)) { - return true; - } - const constraint = getBaseConstraintOfType(t); - if (constraint && constraint !== t) { - return !isRelated(constraint, candidate); - } - return false; - }); + return filterType(type, t => !isRelated(t, candidate)); } // If the current type is a union type, remove all constituents that couldn't be instances of // the candidate type. If one or more constituents remain, return a union of those. diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt new file mode 100644 index 0000000000000..e8e8253d0b199 --- /dev/null +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -0,0 +1,196 @@ +tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts(63,84): error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. + Type 'unknown' is not assignable to type 'Shared>'. + Type 'Matching>' is not assignable to type 'Shared>'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + + +==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== + declare class Component

{ + constructor(props: Readonly

); + constructor(props: P, context?: any); + readonly props: Readonly

& Readonly<{ children?: {} }>; + } + interface ComponentClass

{ + new (props: P, context?: any): Component

; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; + } + interface FunctionComponent

{ + (props: P & { children?: {} }, context?: any): {} | null; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; + } + + export declare const nominalTypeHack: unique symbol; + export interface Validator { + (props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null; + [nominalTypeHack]?: T; + } + type WeakValidationMap = { + [K in keyof T]?: null extends T[K] + ? Validator + : undefined extends T[K] + ? Validator + : Validator + }; + type ComponentType

= ComponentClass

| FunctionComponent

; + + export type Shared< + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + + // Infers prop type from component C + export type GetProps = C extends ComponentType ? P : never; + + export type ConnectedComponentClass< + C extends ComponentType, + P + > = ComponentClass

& { + WrappedComponent: C; + }; + + export type Matching = { + [P in keyof DecorationTargetProps]: P extends keyof InjectedProps + ? InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : InjectedProps[P] + : DecorationTargetProps[P]; + }; + + export type Omit = Pick>; + + export type InferableComponentEnhancerWithProps = + >>>( + component: C + ) => ConnectedComponentClass, keyof Shared>> & TNeedsProps>; + ~~~~~~~~~~~ +!!! error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. +!!! error TS2344: Type 'unknown' is not assignable to type 'Shared>'. +!!! error TS2344: Type 'Matching>' is not assignable to type 'Shared>'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.errors.txt b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.errors.txt new file mode 100644 index 0000000000000..8f936562109f7 --- /dev/null +++ b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts(9,5): error TS2322: Type 'Stuff' is not assignable to type 'Stuff'. + Type 'U' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. + + +==== tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts (1 errors) ==== + /// + + type Stuff = + T extends keyof JSX.IntrinsicElements + ? JSX.IntrinsicElements[T] + : any; + + function F(p1: Stuff, p2: Stuff) { + p1 = p2; // Error + ~~ +!!! error TS2322: Type 'Stuff' is not assignable to type 'Stuff'. +!!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. + } \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.js b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.js new file mode 100644 index 0000000000000..c799ce6c24626 --- /dev/null +++ b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.js @@ -0,0 +1,17 @@ +//// [conditionalTypeVarianceBigArrayConstraintsPerformance.ts] +/// + +type Stuff = + T extends keyof JSX.IntrinsicElements + ? JSX.IntrinsicElements[T] + : any; + +function F(p1: Stuff, p2: Stuff) { + p1 = p2; // Error +} + +//// [conditionalTypeVarianceBigArrayConstraintsPerformance.js] +/// +function F(p1, p2) { + p1 = p2; // Error +} diff --git a/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.symbols b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.symbols new file mode 100644 index 0000000000000..4ecda5edd63b4 --- /dev/null +++ b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts === +/// + +type Stuff = +>Stuff : Symbol(Stuff, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 2, 11)) + + T extends keyof JSX.IntrinsicElements +>T : Symbol(T, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 2, 11)) +>JSX : Symbol(JSX, Decl(react16.d.ts, 2493, 12)) +>IntrinsicElements : Symbol(JSX.IntrinsicElements, Decl(react16.d.ts, 2514, 86)) + + ? JSX.IntrinsicElements[T] +>JSX : Symbol(JSX, Decl(react16.d.ts, 2493, 12)) +>IntrinsicElements : Symbol(JSX.IntrinsicElements, Decl(react16.d.ts, 2514, 86)) +>T : Symbol(T, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 2, 11)) + + : any; + +function F(p1: Stuff, p2: Stuff) { +>F : Symbol(F, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 5, 14)) +>T : Symbol(T, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 11)) +>U : Symbol(U, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 13)) +>p1 : Symbol(p1, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 17)) +>Stuff : Symbol(Stuff, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 11)) +>p2 : Symbol(p2, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 30)) +>Stuff : Symbol(Stuff, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 0, 0)) +>U : Symbol(U, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 13)) + + p1 = p2; // Error +>p1 : Symbol(p1, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 17)) +>p2 : Symbol(p2, Decl(conditionalTypeVarianceBigArrayConstraintsPerformance.ts, 7, 30)) +} diff --git a/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.types b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.types new file mode 100644 index 0000000000000..d9c8af9b51f7a --- /dev/null +++ b/tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts === +/// + +type Stuff = +>Stuff : Stuff + + T extends keyof JSX.IntrinsicElements +>JSX : any + + ? JSX.IntrinsicElements[T] +>JSX : any + + : any; + +function F(p1: Stuff, p2: Stuff) { +>F : (p1: Stuff, p2: Stuff) => void +>p1 : Stuff +>p2 : Stuff + + p1 = p2; // Error +>p1 = p2 : Stuff +>p1 : Stuff +>p2 : Stuff +} diff --git a/tests/baselines/reference/deepComparisons.errors.txt b/tests/baselines/reference/deepComparisons.errors.txt new file mode 100644 index 0000000000000..43eec648b7fdb --- /dev/null +++ b/tests/baselines/reference/deepComparisons.errors.txt @@ -0,0 +1,49 @@ +tests/cases/compiler/deepComparisons.ts(2,9): error TS2322: Type 'T' is not assignable to type 'Extract'. +tests/cases/compiler/deepComparisons.ts(3,9): error TS2322: Type 'T[K1]' is not assignable to type 'Extract'. + Type 'T[keyof T]' is not assignable to type 'Extract'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract'. + Type 'T[string]' is not assignable to type 'Extract'. +tests/cases/compiler/deepComparisons.ts(4,9): error TS2322: Type 'T[K1][K2]' is not assignable to type 'Extract'. + Type 'T[K1][keyof T[K1]]' is not assignable to type 'Extract'. + Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract'. + Type 'T[K1][string]' is not assignable to type 'Extract'. + Type 'T[keyof T][string]' is not assignable to type 'Extract'. + Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract'. + Type 'T[string][string]' is not assignable to type 'Extract'. + + +==== tests/cases/compiler/deepComparisons.ts (3 errors) ==== + function f1() { + let v1: Extract = 0 as any as T; // Error + ~~ +!!! error TS2322: Type 'T' is not assignable to type 'Extract'. + let v2: Extract = 0 as any as T[K1]; // Error + ~~ +!!! error TS2322: Type 'T[K1]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'Extract'. + let v3: Extract = 0 as any as T[K1][K2]; // No error + ~~ +!!! error TS2322: Type 'T[K1][K2]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[K1][keyof T[K1]]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[K1][string]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[keyof T][string]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract'. +!!! error TS2322: Type 'T[string][string]' is not assignable to type 'Extract'. + } + + type Foo = { x: Foo }; + type Bar = { x: Bar }; + + function f2() { + let x: Foo = 0 as any as Bar; // Error, excessive stack depth + } + + type Foo1 = { x: Foo2 }; + type Foo2 = { x: Foo1 }; + + function f3() { + let x: Foo1 = 0 as any as Bar; // No error! + } \ No newline at end of file diff --git a/tests/baselines/reference/deepComparisons.js b/tests/baselines/reference/deepComparisons.js new file mode 100644 index 0000000000000..95d81ea96cf41 --- /dev/null +++ b/tests/baselines/reference/deepComparisons.js @@ -0,0 +1,33 @@ +//// [deepComparisons.ts] +function f1() { + let v1: Extract = 0 as any as T; // Error + let v2: Extract = 0 as any as T[K1]; // Error + let v3: Extract = 0 as any as T[K1][K2]; // No error +} + +type Foo = { x: Foo }; +type Bar = { x: Bar }; + +function f2() { + let x: Foo = 0 as any as Bar; // Error, excessive stack depth +} + +type Foo1 = { x: Foo2 }; +type Foo2 = { x: Foo1 }; + +function f3() { + let x: Foo1 = 0 as any as Bar; // No error! +} + +//// [deepComparisons.js] +function f1() { + var v1 = 0; // Error + var v2 = 0; // Error + var v3 = 0; // No error +} +function f2() { + var x = 0; // Error, excessive stack depth +} +function f3() { + var x = 0; // No error! +} diff --git a/tests/baselines/reference/deepComparisons.symbols b/tests/baselines/reference/deepComparisons.symbols new file mode 100644 index 0000000000000..4c172345e07ac --- /dev/null +++ b/tests/baselines/reference/deepComparisons.symbols @@ -0,0 +1,86 @@ +=== tests/cases/compiler/deepComparisons.ts === +function f1() { +>f1 : Symbol(f1, Decl(deepComparisons.ts, 0, 0)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K2 : Symbol(K2, Decl(deepComparisons.ts, 0, 34)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) + + let v1: Extract = 0 as any as T; // Error +>v1 : Symbol(v1, Decl(deepComparisons.ts, 1, 7)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) + + let v2: Extract = 0 as any as T[K1]; // Error +>v2 : Symbol(v2, Decl(deepComparisons.ts, 2, 7)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) + + let v3: Extract = 0 as any as T[K1][K2]; // No error +>v3 : Symbol(v3, Decl(deepComparisons.ts, 3, 7)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) +>K2 : Symbol(K2, Decl(deepComparisons.ts, 0, 34)) +>T : Symbol(T, Decl(deepComparisons.ts, 0, 12)) +>K1 : Symbol(K1, Decl(deepComparisons.ts, 0, 14)) +>K2 : Symbol(K2, Decl(deepComparisons.ts, 0, 34)) +} + +type Foo = { x: Foo }; +>Foo : Symbol(Foo, Decl(deepComparisons.ts, 4, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 6, 9)) +>x : Symbol(x, Decl(deepComparisons.ts, 6, 15)) +>Foo : Symbol(Foo, Decl(deepComparisons.ts, 4, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 6, 9)) + +type Bar = { x: Bar }; +>Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28)) +>T : Symbol(T, Decl(deepComparisons.ts, 7, 9)) +>x : Symbol(x, Decl(deepComparisons.ts, 7, 15)) +>Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28)) +>T : Symbol(T, Decl(deepComparisons.ts, 7, 9)) + +function f2() { +>f2 : Symbol(f2, Decl(deepComparisons.ts, 7, 30)) +>U : Symbol(U, Decl(deepComparisons.ts, 9, 12)) + + let x: Foo = 0 as any as Bar; // Error, excessive stack depth +>x : Symbol(x, Decl(deepComparisons.ts, 10, 7)) +>Foo : Symbol(Foo, Decl(deepComparisons.ts, 4, 1)) +>U : Symbol(U, Decl(deepComparisons.ts, 9, 12)) +>Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28)) +>U : Symbol(U, Decl(deepComparisons.ts, 9, 12)) +} + +type Foo1 = { x: Foo2 }; +>Foo1 : Symbol(Foo1, Decl(deepComparisons.ts, 11, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 13, 10)) +>x : Symbol(x, Decl(deepComparisons.ts, 13, 16)) +>Foo2 : Symbol(Foo2, Decl(deepComparisons.ts, 13, 30)) +>T : Symbol(T, Decl(deepComparisons.ts, 13, 10)) + +type Foo2 = { x: Foo1 }; +>Foo2 : Symbol(Foo2, Decl(deepComparisons.ts, 13, 30)) +>T : Symbol(T, Decl(deepComparisons.ts, 14, 10)) +>x : Symbol(x, Decl(deepComparisons.ts, 14, 16)) +>Foo1 : Symbol(Foo1, Decl(deepComparisons.ts, 11, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 14, 10)) + +function f3() { +>f3 : Symbol(f3, Decl(deepComparisons.ts, 14, 30)) +>U : Symbol(U, Decl(deepComparisons.ts, 16, 12)) + + let x: Foo1 = 0 as any as Bar; // No error! +>x : Symbol(x, Decl(deepComparisons.ts, 17, 7)) +>Foo1 : Symbol(Foo1, Decl(deepComparisons.ts, 11, 1)) +>U : Symbol(U, Decl(deepComparisons.ts, 16, 12)) +>Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28)) +>U : Symbol(U, Decl(deepComparisons.ts, 16, 12)) +} diff --git a/tests/baselines/reference/deepComparisons.types b/tests/baselines/reference/deepComparisons.types new file mode 100644 index 0000000000000..7bc16b70f8a64 --- /dev/null +++ b/tests/baselines/reference/deepComparisons.types @@ -0,0 +1,58 @@ +=== tests/cases/compiler/deepComparisons.ts === +function f1() { +>f1 : () => void + + let v1: Extract = 0 as any as T; // Error +>v1 : Extract +>0 as any as T : T +>0 as any : any +>0 : 0 + + let v2: Extract = 0 as any as T[K1]; // Error +>v2 : Extract +>0 as any as T[K1] : T[K1] +>0 as any : any +>0 : 0 + + let v3: Extract = 0 as any as T[K1][K2]; // No error +>v3 : Extract +>0 as any as T[K1][K2] : T[K1][K2] +>0 as any : any +>0 : 0 +} + +type Foo = { x: Foo }; +>Foo : Foo +>x : Foo + +type Bar = { x: Bar }; +>Bar : Bar +>x : Bar + +function f2() { +>f2 : () => void + + let x: Foo = 0 as any as Bar; // Error, excessive stack depth +>x : Foo +>0 as any as Bar : Bar +>0 as any : any +>0 : 0 +} + +type Foo1 = { x: Foo2 }; +>Foo1 : Foo1 +>x : Foo2 + +type Foo2 = { x: Foo1 }; +>Foo2 : Foo2 +>x : Foo1 + +function f3() { +>f3 : () => void + + let x: Foo1 = 0 as any as Bar; // No error! +>x : Foo1 +>0 as any as Bar : Bar +>0 as any : any +>0 : 0 +} diff --git a/tests/baselines/reference/genericCapturingFunctionNarrowing.js b/tests/baselines/reference/genericCapturingFunctionNarrowing.js new file mode 100644 index 0000000000000..8a5fd504ea1b6 --- /dev/null +++ b/tests/baselines/reference/genericCapturingFunctionNarrowing.js @@ -0,0 +1,28 @@ +//// [genericCapturingFunctionNarrowing.ts] +function needsToNarrowTheType(thing: First | SubFirst | SubFirstMore | Second) { + if (hasAFoo(thing)) { + console.log(thing.foo); + } + else { + // I would expect this to work because the type should be narrowed in this branch to `Second` + console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'. + } + + function hasAFoo(value: First | Second): value is First { + return "foo" in value; + } +} + +//// [genericCapturingFunctionNarrowing.js] +function needsToNarrowTheType(thing) { + if (hasAFoo(thing)) { + console.log(thing.foo); + } + else { + // I would expect this to work because the type should be narrowed in this branch to `Second` + console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'. + } + function hasAFoo(value) { + return "foo" in value; + } +} diff --git a/tests/baselines/reference/genericCapturingFunctionNarrowing.symbols b/tests/baselines/reference/genericCapturingFunctionNarrowing.symbols new file mode 100644 index 0000000000000..5a77f325d16ac --- /dev/null +++ b/tests/baselines/reference/genericCapturingFunctionNarrowing.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/genericCapturingFunctionNarrowing.ts === +function needsToNarrowTheType(thing: First | SubFirst | SubFirstMore | Second) { +>needsToNarrowTheType : Symbol(needsToNarrowTheType, Decl(genericCapturingFunctionNarrowing.ts, 0, 0)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) +>foo : Symbol(foo, Decl(genericCapturingFunctionNarrowing.ts, 0, 45)) +>Second : Symbol(Second, Decl(genericCapturingFunctionNarrowing.ts, 0, 60)) +>bar : Symbol(bar, Decl(genericCapturingFunctionNarrowing.ts, 0, 77)) +>SubFirst : Symbol(SubFirst, Decl(genericCapturingFunctionNarrowing.ts, 0, 92)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) +>SubFirstMore : Symbol(SubFirstMore, Decl(genericCapturingFunctionNarrowing.ts, 0, 116)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) +>other : Symbol(other, Decl(genericCapturingFunctionNarrowing.ts, 0, 147)) +>thing : Symbol(thing, Decl(genericCapturingFunctionNarrowing.ts, 0, 163)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) +>SubFirst : Symbol(SubFirst, Decl(genericCapturingFunctionNarrowing.ts, 0, 92)) +>SubFirstMore : Symbol(SubFirstMore, Decl(genericCapturingFunctionNarrowing.ts, 0, 116)) +>Second : Symbol(Second, Decl(genericCapturingFunctionNarrowing.ts, 0, 60)) + + if (hasAFoo(thing)) { +>hasAFoo : Symbol(hasAFoo, Decl(genericCapturingFunctionNarrowing.ts, 7, 5)) +>thing : Symbol(thing, Decl(genericCapturingFunctionNarrowing.ts, 0, 163)) + + console.log(thing.foo); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>thing.foo : Symbol(foo, Decl(genericCapturingFunctionNarrowing.ts, 0, 45)) +>thing : Symbol(thing, Decl(genericCapturingFunctionNarrowing.ts, 0, 163)) +>foo : Symbol(foo, Decl(genericCapturingFunctionNarrowing.ts, 0, 45)) + } + else { + // I would expect this to work because the type should be narrowed in this branch to `Second` + console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'. +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>thing.bar : Symbol(bar, Decl(genericCapturingFunctionNarrowing.ts, 0, 77)) +>thing : Symbol(thing, Decl(genericCapturingFunctionNarrowing.ts, 0, 163)) +>bar : Symbol(bar, Decl(genericCapturingFunctionNarrowing.ts, 0, 77)) + } + + function hasAFoo(value: First | Second): value is First { +>hasAFoo : Symbol(hasAFoo, Decl(genericCapturingFunctionNarrowing.ts, 7, 5)) +>value : Symbol(value, Decl(genericCapturingFunctionNarrowing.ts, 9, 21)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) +>Second : Symbol(Second, Decl(genericCapturingFunctionNarrowing.ts, 0, 60)) +>value : Symbol(value, Decl(genericCapturingFunctionNarrowing.ts, 9, 21)) +>First : Symbol(First, Decl(genericCapturingFunctionNarrowing.ts, 0, 30)) + + return "foo" in value; +>value : Symbol(value, Decl(genericCapturingFunctionNarrowing.ts, 9, 21)) + } +} diff --git a/tests/baselines/reference/genericCapturingFunctionNarrowing.types b/tests/baselines/reference/genericCapturingFunctionNarrowing.types new file mode 100644 index 0000000000000..d46f4540745c7 --- /dev/null +++ b/tests/baselines/reference/genericCapturingFunctionNarrowing.types @@ -0,0 +1,44 @@ +=== tests/cases/compiler/genericCapturingFunctionNarrowing.ts === +function needsToNarrowTheType(thing: First | SubFirst | SubFirstMore | Second) { +>needsToNarrowTheType : (thing: First | SubFirst | SubFirstMore | Second) => void +>foo : string +>bar : string +>other : string +>thing : First | Second | SubFirst | SubFirstMore + + if (hasAFoo(thing)) { +>hasAFoo(thing) : boolean +>hasAFoo : (value: First | Second) => value is First +>thing : First | Second | SubFirst | SubFirstMore + + console.log(thing.foo); +>console.log(thing.foo) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>thing.foo : string +>thing : First | SubFirst | SubFirstMore +>foo : string + } + else { + // I would expect this to work because the type should be narrowed in this branch to `Second` + console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'. +>console.log(thing.bar) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>thing.bar : string +>thing : Second +>bar : string + } + + function hasAFoo(value: First | Second): value is First { +>hasAFoo : (value: First | Second) => value is First +>value : First | Second + + return "foo" in value; +>"foo" in value : boolean +>"foo" : "foo" +>value : First | Second + } +} diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt new file mode 100644 index 0000000000000..5d74b6e23b504 --- /dev/null +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt @@ -0,0 +1,54 @@ +tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts(13,5): error TS2322: Type 'ReturnType' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. + Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. + Type 'ReturnType[string]>' is not assignable to type 'A'. + Property 'x' is missing in type '{}' but required in type 'A'. + + +==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ==== + interface A { x: number } + + declare function isA(a: unknown): a is A; + + type FunctionsObj = { + [K in keyof T]: () => unknown + } + + function g< + T extends FunctionsObj, + M extends keyof T + >(a2: ReturnType, x: A) { + x = a2; + ~ +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. +!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. +!!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here. + } + + // Original CFA report of the above issue + + function g2< + T extends FunctionsObj, + M extends keyof T + >(a2: ReturnType) { + if (isA(a2)) { + // a2 is not narrowed + a2.x // error, but should be ok + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.js b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.js new file mode 100644 index 0000000000000..665312081ac69 --- /dev/null +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.js @@ -0,0 +1,40 @@ +//// [genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts] +interface A { x: number } + +declare function isA(a: unknown): a is A; + +type FunctionsObj = { + [K in keyof T]: () => unknown +} + +function g< + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType, x: A) { + x = a2; +} + +// Original CFA report of the above issue + +function g2< + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType) { + if (isA(a2)) { + // a2 is not narrowed + a2.x // error, but should be ok + } +} + + +//// [genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.js] +function g(a2, x) { + x = a2; +} +// Original CFA report of the above issue +function g2(a2) { + if (isA(a2)) { + // a2 is not narrowed + a2.x; // error, but should be ok + } +} diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.symbols b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.symbols new file mode 100644 index 0000000000000..6524df5efcb06 --- /dev/null +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.symbols @@ -0,0 +1,77 @@ +=== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts === +interface A { x: number } +>A : Symbol(A, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 0)) +>x : Symbol(A.x, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 13)) + +declare function isA(a: unknown): a is A; +>isA : Symbol(isA, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 25)) +>a : Symbol(a, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 2, 21)) +>a : Symbol(a, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 2, 21)) +>A : Symbol(A, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 0)) + +type FunctionsObj = { +>FunctionsObj : Symbol(FunctionsObj, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 2, 41)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 4, 18)) + + [K in keyof T]: () => unknown +>K : Symbol(K, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 5, 5)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 4, 18)) +} + +function g< +>g : Symbol(g, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 6, 1)) + + T extends FunctionsObj, +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 8, 11)) +>FunctionsObj : Symbol(FunctionsObj, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 2, 41)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 8, 11)) + + M extends keyof T +>M : Symbol(M, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 9, 30)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 8, 11)) + +>(a2: ReturnType, x: A) { +>a2 : Symbol(a2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 11, 2)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 8, 11)) +>M : Symbol(M, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 9, 30)) +>x : Symbol(x, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 11, 23)) +>A : Symbol(A, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 0)) + + x = a2; +>x : Symbol(x, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 11, 23)) +>a2 : Symbol(a2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 11, 2)) +} + +// Original CFA report of the above issue + +function g2< +>g2 : Symbol(g2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 13, 1)) + + T extends FunctionsObj, +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 17, 12)) +>FunctionsObj : Symbol(FunctionsObj, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 2, 41)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 17, 12)) + + M extends keyof T +>M : Symbol(M, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 18, 30)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 17, 12)) + +>(a2: ReturnType) { +>a2 : Symbol(a2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 20, 2)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 17, 12)) +>M : Symbol(M, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 18, 30)) + + if (isA(a2)) { +>isA : Symbol(isA, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 25)) +>a2 : Symbol(a2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 20, 2)) + + // a2 is not narrowed + a2.x // error, but should be ok +>a2.x : Symbol(A.x, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 13)) +>a2 : Symbol(a2, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 20, 2)) +>x : Symbol(A.x, Decl(genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts, 0, 13)) + } +} + diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.types b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.types new file mode 100644 index 0000000000000..3129f99e5f0cf --- /dev/null +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.types @@ -0,0 +1,52 @@ +=== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts === +interface A { x: number } +>x : number + +declare function isA(a: unknown): a is A; +>isA : (a: unknown) => a is A +>a : unknown + +type FunctionsObj = { +>FunctionsObj : FunctionsObj + + [K in keyof T]: () => unknown +} + +function g< +>g : , M extends keyof T>(a2: ReturnType, x: A) => void + + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType, x: A) { +>a2 : ReturnType +>x : A + + x = a2; +>x = a2 : ReturnType +>x : A +>a2 : ReturnType +} + +// Original CFA report of the above issue + +function g2< +>g2 : , M extends keyof T>(a2: ReturnType) => void + + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType) { +>a2 : ReturnType + + if (isA(a2)) { +>isA(a2) : boolean +>isA : (a: unknown) => a is A +>a2 : ReturnType + + // a2 is not narrowed + a2.x // error, but should be ok +>a2.x : number +>a2 : ReturnType & A +>x : number + } +} + diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index 0a9cd55b14ebb..c3101af493e9c 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -2,9 +2,10 @@ tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' ca tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Value<"dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Value<"dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. +tests/cases/compiler/infiniteConstraints.ts(48,27): error TS2321: Excessive stack depth comparing types 'Conv, ExactExtract>' and 'unknown[]'. -==== tests/cases/compiler/infiniteConstraints.ts (4 errors) ==== +==== tests/cases/compiler/infiniteConstraints.ts (5 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -63,4 +64,6 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c type Conv = { 0: [T]; 1: Prepend>>;}[U extends T ? 0 : 1]; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2321: Excessive stack depth comparing types 'Conv, ExactExtract>' and 'unknown[]'. \ No newline at end of file diff --git a/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.errors.txt b/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.errors.txt index 15d2835790b00..3791e82e28c0b 100644 --- a/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.errors.txt +++ b/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.errors.txt @@ -1,11 +1,8 @@ tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts(33,15): error TS2339: Property 'numExclusive' does not exist on type 'NumClass | StrClass'. Property 'numExclusive' does not exist on type 'StrClass'. -tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts(101,11): error TS2322: Type 'Program | T' is not assignable to type 'Program'. - Type 'T' is not assignable to type 'Program'. - Property 'state' is missing in type 'BuilderProgram' but required in type 'Program'. -==== tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts (2 errors) ==== +==== tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts (1 errors) ==== class NumClass { private value!: T; public get(): T { @@ -110,9 +107,4 @@ tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts(101,11): error declare function isBuilderProgram(program: Program | T): program is T; export function listFiles(program: Program | T) { const x: Program = isBuilderProgram(program) ? program.getProgram() : program; - ~ -!!! error TS2322: Type 'Program | T' is not assignable to type 'Program'. -!!! error TS2322: Type 'T' is not assignable to type 'Program'. -!!! error TS2322: Property 'state' is missing in type 'BuilderProgram' but required in type 'Program'. -!!! related TS2728 tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts:97:5: 'state' is declared here. } \ No newline at end of file diff --git a/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.types b/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.types index 9d0e23dc6a884..1782050b8f261 100644 --- a/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.types +++ b/tests/baselines/reference/quickinfoTypeAtReturnPositionsInaccurate.types @@ -226,7 +226,7 @@ export function listFiles(program: Program | T) { const x: Program = isBuilderProgram(program) ? program.getProgram() : program; >x : Program ->isBuilderProgram(program) ? program.getProgram() : program : Program | T +>isBuilderProgram(program) ? program.getProgram() : program : Program >isBuilderProgram(program) : boolean >isBuilderProgram : (program: Program | T) => program is T >program : Program | T @@ -234,5 +234,5 @@ export function listFiles(program: Program | T) { >program.getProgram : () => Program >program : T >getProgram : () => Program ->program : Program | T +>program : Program } diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt new file mode 100644 index 0000000000000..ec97973b68731 --- /dev/null +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -0,0 +1,279 @@ +tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. + Type 'unknown' is not assignable to type 'Shared>'. + Type 'Matching>' is not assignable to type 'Shared>'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + + +==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== + declare class Component

{ + constructor(props: Readonly

); + constructor(props: P, context?: any); + readonly props: Readonly

& Readonly<{ children?: {} }>; + } + interface ComponentClass

{ + new (props: P, context?: any): Component

; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; + } + interface FunctionComponent

{ + (props: P & { children?: {} }, context?: any): {} | null; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; + } + + declare const nominalTypeHack: unique symbol; + interface Validator { + ( + props: object, + propName: string, + componentName: string, + location: string, + propFullName: string + ): Error | null; + [nominalTypeHack]?: T; + } + type WeakValidationMap = { + [K in keyof T]?: null extends T[K] + ? Validator + : undefined extends T[K] + ? Validator + : Validator + }; + type ComponentType

= ComponentClass

| FunctionComponent

; + + type Shared< + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract< + keyof InjectedProps, + keyof DecorationTargetProps + >]?: InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : never + }; + + // Infers prop type from component C + type GetProps = C extends ComponentType ? P : never; + + type ConnectedComponentClass, P> = ComponentClass< + P + > & { + WrappedComponent: C; + }; + + type Matching = { + [P in keyof DecorationTargetProps]: P extends keyof InjectedProps + ? InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : InjectedProps[P] + : DecorationTargetProps[P] + }; + + type Omit = Pick>; + + type InferableComponentEnhancerWithProps = < + C extends ComponentType>> + >( + component: C + ) => ConnectedComponentClass< + C, + Omit, keyof Shared>> & TNeedsProps + ~~~~~~~~~~~ +!!! error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. +!!! error TS2344: Type 'unknown' is not assignable to type 'Shared>'. +!!! error TS2344: Type 'Matching>' is not assignable to type 'Shared>'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + >; + + declare const connect: { + ( + mapStateToProps: null | undefined, + mapDispatchToProps: TDispatchProps + ): InferableComponentEnhancerWithProps< + ResolveThunks, + TOwnProps + >; + }; + + type InferThunkActionCreatorType< + TActionCreator extends (...args: any[]) => any + > = TActionCreator extends ( + ...args: infer TParams + ) => (...args: any[]) => infer TReturn + ? (...args: TParams) => TReturn + : TActionCreator; + + type HandleThunkActionCreator = TActionCreator extends ( + ...args: any[] + ) => any + ? InferThunkActionCreatorType + : TActionCreator; + + type ResolveThunks = TDispatchProps extends { + [key: string]: any; + } + ? { [C in keyof TDispatchProps]: HandleThunkActionCreator } + : TDispatchProps; + + interface Dispatch { + (action: T): T; + } + interface Action { + type: T; + } + interface AnyAction extends Action { + [extraProps: string]: any; + } + + const simpleAction = (payload: boolean) => ({ + type: "SIMPLE_ACTION", + payload + }); + const thunkAction = (param1: number, param2: string) => async ( + dispatch: Dispatch, + { foo }: OwnProps + ) => { + return foo; + }; + interface OwnProps { + foo: string; + } + interface TestComponentProps extends OwnProps { + simpleAction: typeof simpleAction; + thunkAction(param1: number, param2: string): Promise; + } + class TestComponent extends Component {} + const mapDispatchToProps = { simpleAction, thunkAction }; + + type Q = HandleThunkActionCreator; + + const Test1 = connect( + null, + mapDispatchToProps + )(TestComponent); + + export {}; + \ No newline at end of file diff --git a/tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts b/tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts new file mode 100644 index 0000000000000..801c848ef1877 --- /dev/null +++ b/tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts @@ -0,0 +1,11 @@ +// @skipLibCheck: true +/// + +type Stuff = + T extends keyof JSX.IntrinsicElements + ? JSX.IntrinsicElements[T] + : any; + +function F(p1: Stuff, p2: Stuff) { + p1 = p2; // Error +} \ No newline at end of file diff --git a/tests/cases/compiler/deepComparisons.ts b/tests/cases/compiler/deepComparisons.ts new file mode 100644 index 0000000000000..1323673945a58 --- /dev/null +++ b/tests/cases/compiler/deepComparisons.ts @@ -0,0 +1,19 @@ +function f1() { + let v1: Extract = 0 as any as T; // Error + let v2: Extract = 0 as any as T[K1]; // Error + let v3: Extract = 0 as any as T[K1][K2]; // No error +} + +type Foo = { x: Foo }; +type Bar = { x: Bar }; + +function f2() { + let x: Foo = 0 as any as Bar; // Error, excessive stack depth +} + +type Foo1 = { x: Foo2 }; +type Foo2 = { x: Foo1 }; + +function f3() { + let x: Foo1 = 0 as any as Bar; // No error! +} \ No newline at end of file diff --git a/tests/cases/compiler/genericCapturingFunctionNarrowing.ts b/tests/cases/compiler/genericCapturingFunctionNarrowing.ts new file mode 100644 index 0000000000000..69b1ca05600a0 --- /dev/null +++ b/tests/cases/compiler/genericCapturingFunctionNarrowing.ts @@ -0,0 +1,13 @@ +function needsToNarrowTheType(thing: First | SubFirst | SubFirstMore | Second) { + if (hasAFoo(thing)) { + console.log(thing.foo); + } + else { + // I would expect this to work because the type should be narrowed in this branch to `Second` + console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'. + } + + function hasAFoo(value: First | Second): value is First { + return "foo" in value; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts b/tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts new file mode 100644 index 0000000000000..52e411c56107b --- /dev/null +++ b/tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts @@ -0,0 +1,26 @@ +interface A { x: number } + +declare function isA(a: unknown): a is A; + +type FunctionsObj = { + [K in keyof T]: () => unknown +} + +function g< + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType, x: A) { + x = a2; +} + +// Original CFA report of the above issue + +function g2< + T extends FunctionsObj, + M extends keyof T +>(a2: ReturnType) { + if (isA(a2)) { + // a2 is not narrowed + a2.x // error, but should be ok + } +}