diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f56f56223cf5a..27c8a027cbcba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15310,7 +15310,7 @@ namespace ts { objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || objectFlags & ObjectFlags.Mapped || - type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(type)); + type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && couldUnionOrIntersectionContainTypeVariables(type)); } function couldUnionOrIntersectionContainTypeVariables(type: UnionOrIntersectionType): boolean { @@ -15462,7 +15462,7 @@ namespace ts { let visited: Map; let bivariant = false; let propagationType: Type; - let inferenceCount = 0; + let inferenceMatch = false; let inferenceIncomplete = false; let allowComplexConstraintInference = true; inferFromTypes(originalSource, originalTarget); @@ -15487,46 +15487,50 @@ namespace ts { inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol)); return; } - if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) || - source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) { - // Source and target are both unions or both intersections. If source and target - // are the same type, just relate each constituent type to itself. - if (source === target) { - for (const t of (source).types) { - inferFromTypes(t, t); + if (source === target && source.flags & TypeFlags.UnionOrIntersection) { + // When source and target are the same union or intersection type, just relate each constituent + // type to itself. + for (const t of (source).types) { + inferFromTypes(t, t); + } + return; + } + if (target.flags & TypeFlags.Union) { + if (source.flags & TypeFlags.Union) { + // First, infer between identically matching source and target constituents and remove the + // matching types. + const [tempSources, tempTargets] = inferFromMatchingTypes((source).types, (target).types, isTypeOrBaseIdenticalTo); + // Next, infer between closely matching source and target constituents and remove + // the matching types. Types closely match when they are instantiations of the same + // object type or instantiations of the same type alias. + const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy); + if (sources.length === 0 || targets.length === 0) { + return; } - return; + source = getUnionType(sources); + target = getUnionType(targets); } - // Find each source constituent type that has an identically matching target constituent - // type, and for each such type infer from the type to itself. When inferring from a - // type to itself we effectively find all type parameter occurrences within that type - // and infer themselves as their type arguments. We have special handling for numeric - // and string literals because the number and string types are not represented as unions - // of all their possible values. - let matchingTypes: Type[] | undefined; - for (const t of (source).types) { - const matched = findMatchedType(t, target); - if (matched) { - (matchingTypes || (matchingTypes = [])).push(matched); - inferFromTypes(matched, matched); - } - } - // Next, to improve the quality of inferences, reduce the source and target types by - // removing the identically matched constituents. For example, when inferring from - // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'. - if (matchingTypes) { - const s = removeTypesFromUnionOrIntersection(source, matchingTypes); - const t = removeTypesFromUnionOrIntersection(target, matchingTypes); - if (!(s && t)) return; - source = s; - target = t; - } - } - else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) { - const matched = findMatchedType(source, target); - if (matched) { - inferFromTypes(matched, matched); - return; + else { + if (inferFromMatchingType(source, (target).types, isTypeOrBaseIdenticalTo)) return; + if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; + } + } + else if (target.flags & TypeFlags.Intersection && some((target).types, t => !!getInferenceInfoForType(t))) { + // We reduce intersection types only when they contain naked type parameters. For example, when + // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and + // infer { extra: any } for T. But when inferring to 'string[] & Iterable' we want to keep the + // string[] on the source side and infer string for T. + if (source.flags & TypeFlags.Intersection) { + // Infer between identically matching source and target constituents and remove the matching types. + const [sources, targets] = inferFromMatchingTypes((source).types, (target).types, isTypeIdenticalTo); + if (sources.length === 0 || targets.length === 0) { + return; + } + source = getIntersectionType(sources); + target = getIntersectionType(targets); + } + else if (!(source.flags & TypeFlags.Union)) { + if (inferFromMatchingType(source, (target).types, isTypeIdenticalTo)) return; } } else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { @@ -15572,7 +15576,7 @@ namespace ts { clearCachedInferences(inferences); } } - inferenceCount++; + inferenceMatch = true; return; } else { @@ -15664,15 +15668,50 @@ namespace ts { function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) { const key = source.id + "," + target.id; - const count = visited && visited.get(key); - if (count !== undefined) { - inferenceCount += count; + const status = visited && visited.get(key); + if (status !== undefined) { + if (status & 1) inferenceMatch = true; + if (status & 2) inferenceIncomplete = true; return; } (visited || (visited = createMap())).set(key, 0); - const startCount = inferenceCount; + const saveInferenceMatch = inferenceMatch; + const saveInferenceIncomplete = inferenceIncomplete; + inferenceMatch = false; + inferenceIncomplete = false; action(source, target); - visited.set(key, inferenceCount - startCount); + visited.set(key, (inferenceMatch ? 1 : 0) | (inferenceIncomplete ? 2 : 0)); + inferenceMatch = inferenceMatch || saveInferenceMatch; + inferenceIncomplete = inferenceIncomplete || saveInferenceIncomplete; + } + + function inferFromMatchingType(source: Type, targets: Type[], matches: (s: Type, t: Type) => boolean) { + let matched = false; + for (const t of targets) { + if (matches(source, t)) { + inferFromTypes(source, t); + matched = true; + } + } + return matched; + } + + function inferFromMatchingTypes(sources: Type[], targets: Type[], matches: (s: Type, t: Type) => boolean): [Type[], Type[]] { + let matchedSources: Type[] | undefined; + let matchedTargets: Type[] | undefined; + for (const t of targets) { + for (const s of sources) { + if (matches(s, t)) { + inferFromTypes(s, t); + matchedSources = appendIfUnique(matchedSources, s); + matchedTargets = appendIfUnique(matchedTargets, t); + } + } + } + return [ + matchedSources ? filter(sources, t => !contains(matchedSources, t)) : sources, + matchedTargets ? filter(targets, t => !contains(matchedTargets, t)) : targets, + ]; } function inferFromTypeArguments(sourceTypes: readonly Type[], targetTypes: readonly Type[], variances: readonly VarianceFlags[]) { @@ -15726,9 +15765,11 @@ namespace ts { } else { for (let i = 0; i < sources.length; i++) { - const count = inferenceCount; + const saveInferenceMatch = inferenceMatch; + inferenceMatch = false; inferFromTypes(sources[i], t); - if (count !== inferenceCount) matched[i] = true; + if (inferenceMatch) matched[i] = true; + inferenceMatch = inferenceMatch || saveInferenceMatch; } } } @@ -15955,47 +15996,13 @@ namespace ts { } } - function isMatchableType(type: Type) { - // We exclude non-anonymous object types because some frameworks (e.g. Ember) rely on the ability to - // infer between types that don't witness their type variables. Such types would otherwise be eliminated - // because they appear identical. - return !(type.flags & TypeFlags.Object) || !!(getObjectFlags(type) & ObjectFlags.Anonymous); - } - - function typeMatchedBySomeType(type: Type, types: Type[]): boolean { - for (const t of types) { - if (t === type || isMatchableType(t) && isMatchableType(type) && isTypeIdenticalTo(t, type)) { - return true; - } - } - return false; - } - - function findMatchedType(type: Type, target: UnionOrIntersectionType) { - if (typeMatchedBySomeType(type, target.types)) { - return type; - } - if (type.flags & (TypeFlags.NumberLiteral | TypeFlags.StringLiteral) && target.flags & TypeFlags.Union) { - const base = getBaseTypeOfLiteralType(type); - if (typeMatchedBySomeType(base, target.types)) { - return base; - } - } - return undefined; + function isTypeOrBaseIdenticalTo(s: Type, t: Type) { + return isTypeIdenticalTo(s, t) || !!(s.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) && isTypeIdenticalTo(getBaseTypeOfLiteralType(s), t); } - /** - * Return a new union or intersection type computed by removing a given set of types - * from a given union or intersection type. - */ - function removeTypesFromUnionOrIntersection(type: UnionOrIntersectionType, typesToRemove: Type[]) { - const reducedTypes: Type[] = []; - for (const t of type.types) { - if (!typeMatchedBySomeType(t, typesToRemove)) { - reducedTypes.push(t); - } - } - return reducedTypes.length ? type.flags & TypeFlags.Union ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes) : undefined; + function isTypeCloselyMatchedBy(s: Type, t: Type) { + return !!(s.flags & TypeFlags.Object && t.flags & TypeFlags.Object && s.symbol && s.symbol === t.symbol || + s.aliasSymbol && s.aliasTypeArguments && s.aliasSymbol === t.aliasSymbol); } function hasPrimitiveConstraint(type: TypeParameter): boolean { diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index c7a323f12836f..4fad6997145ff 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -45,14 +45,11 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin Type 'TInjectedProps[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 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & 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 '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 '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 '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 '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 '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 '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 '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 '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'. ==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -167,12 +164,9 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin !!! error TS2344: Type 'TInjectedProps[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 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & 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 '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 '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 '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 '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 '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 '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 '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 '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'. \ No newline at end of file diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 0556ae25c9160..0acfd4a836572 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -45,14 +45,11 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): Type 'TInjectedProps[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 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & 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 '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 '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 '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 '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 '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 '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 '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 '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'. ==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -180,14 +177,11 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): !!! error TS2344: Type 'TInjectedProps[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 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & 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 '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 '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 '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 '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 '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 '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 '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 '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'. >; declare const connect: { diff --git a/tests/baselines/reference/unionAndIntersectionInference3.js b/tests/baselines/reference/unionAndIntersectionInference3.js index 4cc0c2f667e59..415d98220a576 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.js +++ b/tests/baselines/reference/unionAndIntersectionInference3.js @@ -4,9 +4,69 @@ type Maybe = T | undefined; declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); + +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { + throw com; +}; + +interface Foo1 { + test(value: T): void; +} + +interface Bar1 { + test(value: T | PromiseLike): void; +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +declare let f2: (x: Foo1 | Bar1) => Promise; + +f1 = f2; +f2 = f1; + +type Foo2 = { + test(value: T): void; +} + +type Bar2 = { + test(value: T | PromiseLike): void; +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +declare let g2: (x: Foo2 | Bar2) => Promise; + +g1 = g2; +g2 = g1; + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +declare function foo2(obj: string[] & T): T; + +declare let sa: string[]; +declare let sx: string[] & { extra: number }; + +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string + +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number } //// [unionAndIntersectionInference3.js] "use strict"; // Repro from #30720 concatMaybe([1, 2, 3], 4); +// Repros from #32247 +const g = async (com) => { + throw com; +}; +f1 = f2; +f2 = f1; +g1 = g2; +g2 = g1; +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number } diff --git a/tests/baselines/reference/unionAndIntersectionInference3.symbols b/tests/baselines/reference/unionAndIntersectionInference3.symbols index be24bc0cc7781..1d237951b4fd0 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.symbols +++ b/tests/baselines/reference/unionAndIntersectionInference3.symbols @@ -19,3 +19,189 @@ declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); >concatMaybe : Symbol(concatMaybe, Decl(unionAndIntersectionInference3.ts, 2, 30)) +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { +>g : Symbol(g, Decl(unionAndIntersectionInference3.ts, 8, 5)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 19)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 15)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 12)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 10)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 106)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --)) +>S : Symbol(S, Decl(unionAndIntersectionInference3.ts, 8, 102)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) +>R : Symbol(R, Decl(unionAndIntersectionInference3.ts, 8, 99)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 8, 97)) + + throw com; +>com : Symbol(com, Decl(unionAndIntersectionInference3.ts, 8, 106)) + +}; + +interface Foo1 { +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 12, 15)) + + test(value: T): void; +>test : Symbol(Foo1.test, Decl(unionAndIntersectionInference3.ts, 12, 19)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 13, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 12, 15)) +} + +interface Bar1 { +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) + + test(value: T | PromiseLike): void; +>test : Symbol(Bar1.test, Decl(unionAndIntersectionInference3.ts, 16, 19)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 17, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 16, 15)) +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 20, 20)) +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 20, 17)) + +declare let f2: (x: Foo1 | Bar1) => Promise; +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 21, 20)) +>Foo1 : Symbol(Foo1, Decl(unionAndIntersectionInference3.ts, 10, 2)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>Bar1 : Symbol(Bar1, Decl(unionAndIntersectionInference3.ts, 14, 1)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 21, 17)) + +f1 = f2; +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) + +f2 = f1; +>f2 : Symbol(f2, Decl(unionAndIntersectionInference3.ts, 21, 11)) +>f1 : Symbol(f1, Decl(unionAndIntersectionInference3.ts, 20, 11)) + +type Foo2 = { +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 26, 10)) + + test(value: T): void; +>test : Symbol(test, Decl(unionAndIntersectionInference3.ts, 26, 16)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 27, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 26, 10)) +} + +type Bar2 = { +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) + + test(value: T | PromiseLike): void; +>test : Symbol(test, Decl(unionAndIntersectionInference3.ts, 30, 16)) +>value : Symbol(value, Decl(unionAndIntersectionInference3.ts, 31, 9)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 30, 10)) +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 34, 20)) +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 34, 17)) + +declare let g2: (x: Foo2 | Bar2) => Promise; +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>x : Symbol(x, Decl(unionAndIntersectionInference3.ts, 35, 20)) +>Foo2 : Symbol(Foo2, Decl(unionAndIntersectionInference3.ts, 24, 8)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>Bar2 : Symbol(Bar2, Decl(unionAndIntersectionInference3.ts, 28, 1)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 35, 17)) + +g1 = g2; +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) + +g2 = g1; +>g2 : Symbol(g2, Decl(unionAndIntersectionInference3.ts, 35, 11)) +>g1 : Symbol(g1, Decl(unionAndIntersectionInference3.ts, 34, 11)) + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) +>obj : Symbol(obj, Decl(unionAndIntersectionInference3.ts, 42, 25)) +>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 42, 22)) + +declare function foo2(obj: string[] & T): T; +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) +>obj : Symbol(obj, Decl(unionAndIntersectionInference3.ts, 43, 25)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) +>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 43, 22)) + +declare let sa: string[]; +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +declare let sx: string[] & { extra: number }; +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) +>extra : Symbol(extra, Decl(unionAndIntersectionInference3.ts, 46, 28)) + +let x1 = foo1(sa); // string +>x1 : Symbol(x1, Decl(unionAndIntersectionInference3.ts, 48, 3)) +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +let y1 = foo1(sx); // string +>y1 : Symbol(y1, Decl(unionAndIntersectionInference3.ts, 49, 3)) +>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference3.ts, 38, 8)) +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) + +let x2 = foo2(sa); // unknown +>x2 : Symbol(x2, Decl(unionAndIntersectionInference3.ts, 51, 3)) +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>sa : Symbol(sa, Decl(unionAndIntersectionInference3.ts, 45, 11)) + +let y2 = foo2(sx); // { extra: number } +>y2 : Symbol(y2, Decl(unionAndIntersectionInference3.ts, 52, 3)) +>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57)) +>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11)) + diff --git a/tests/baselines/reference/unionAndIntersectionInference3.types b/tests/baselines/reference/unionAndIntersectionInference3.types index 8497cb1e5161f..fb5074743219a 100644 --- a/tests/baselines/reference/unionAndIntersectionInference3.types +++ b/tests/baselines/reference/unionAndIntersectionInference3.types @@ -17,3 +17,121 @@ concatMaybe([1, 2, 3], 4); >3 : 3 >4 : 4 +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { +>g : (com: () => Iterator | AsyncIterator) => Promise +>com : () => Iterator | AsyncIterator +>async (com: () => Iterator | AsyncIterator): Promise => { throw com;} : (com: () => Iterator | AsyncIterator) => Promise +>com : () => Iterator | AsyncIterator + + throw com; +>com : () => Iterator | AsyncIterator + +}; + +interface Foo1 { + test(value: T): void; +>test : (value: T) => void +>value : T +} + +interface Bar1 { + test(value: T | PromiseLike): void; +>test : (value: T | PromiseLike) => void +>value : T | PromiseLike +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +>f1 : (x: Foo1 | Bar1) => Promise +>x : Foo1 | Bar1 + +declare let f2: (x: Foo1 | Bar1) => Promise; +>f2 : (x: Foo1 | Bar1) => Promise +>x : Foo1 | Bar1 + +f1 = f2; +>f1 = f2 : (x: Foo1 | Bar1) => Promise +>f1 : (x: Foo1 | Bar1) => Promise +>f2 : (x: Foo1 | Bar1) => Promise + +f2 = f1; +>f2 = f1 : (x: Foo1 | Bar1) => Promise +>f2 : (x: Foo1 | Bar1) => Promise +>f1 : (x: Foo1 | Bar1) => Promise + +type Foo2 = { +>Foo2 : Foo2 + + test(value: T): void; +>test : (value: T) => void +>value : T +} + +type Bar2 = { +>Bar2 : Bar2 + + test(value: T | PromiseLike): void; +>test : (value: T | PromiseLike) => void +>value : T | PromiseLike +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +>g1 : (x: Foo2 | Bar2) => Promise +>x : Foo2 | Bar2 + +declare let g2: (x: Foo2 | Bar2) => Promise; +>g2 : (x: Foo2 | Bar2) => Promise +>x : Foo2 | Bar2 + +g1 = g2; +>g1 = g2 : (x: Foo2 | Bar2) => Promise +>g1 : (x: Foo2 | Bar2) => Promise +>g2 : (x: Foo2 | Bar2) => Promise + +g2 = g1; +>g2 = g1 : (x: Foo2 | Bar2) => Promise +>g2 : (x: Foo2 | Bar2) => Promise +>g1 : (x: Foo2 | Bar2) => Promise + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +>foo1 : (obj: string[] & Iterable) => T +>obj : string[] & Iterable + +declare function foo2(obj: string[] & T): T; +>foo2 : (obj: string[] & T) => T +>obj : string[] & T + +declare let sa: string[]; +>sa : string[] + +declare let sx: string[] & { extra: number }; +>sx : string[] & { extra: number; } +>extra : number + +let x1 = foo1(sa); // string +>x1 : string +>foo1(sa) : string +>foo1 : (obj: string[] & Iterable) => T +>sa : string[] + +let y1 = foo1(sx); // string +>y1 : string +>foo1(sx) : string +>foo1 : (obj: string[] & Iterable) => T +>sx : string[] & { extra: number; } + +let x2 = foo2(sa); // unknown +>x2 : unknown +>foo2(sa) : unknown +>foo2 : (obj: string[] & T) => T +>sa : string[] + +let y2 = foo2(sx); // { extra: number } +>y2 : { extra: number; } +>foo2(sx) : { extra: number; } +>foo2 : (obj: string[] & T) => T +>sx : string[] & { extra: number; } + diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts index aad083a626b26..d64b19736952f 100644 --- a/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts +++ b/tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts @@ -1,7 +1,56 @@ // @strict: true +// @target: esnext // Repro from #30720 type Maybe = T | undefined; declare function concatMaybe(...args: (Maybe | Maybe[])[]): T[]; concatMaybe([1, 2, 3], 4); + +// Repros from #32247 + +const g: (com: () => Iterator | AsyncIterator) => Promise = async (com: () => Iterator | AsyncIterator): Promise => { + throw com; +}; + +interface Foo1 { + test(value: T): void; +} + +interface Bar1 { + test(value: T | PromiseLike): void; +} + +declare let f1: (x: Foo1 | Bar1) => Promise; +declare let f2: (x: Foo1 | Bar1) => Promise; + +f1 = f2; +f2 = f1; + +type Foo2 = { + test(value: T): void; +} + +type Bar2 = { + test(value: T | PromiseLike): void; +} + +declare let g1: (x: Foo2 | Bar2) => Promise; +declare let g2: (x: Foo2 | Bar2) => Promise; + +g1 = g2; +g2 = g1; + +// Repro from #32572 + +declare function foo1(obj: string[] & Iterable): T; +declare function foo2(obj: string[] & T): T; + +declare let sa: string[]; +declare let sx: string[] & { extra: number }; + +let x1 = foo1(sa); // string +let y1 = foo1(sx); // string + +let x2 = foo2(sa); // unknown +let y2 = foo2(sx); // { extra: number }