The iteration type of overloaded iterator signatures derives from the intersection of their return types (#39722)

This commit is contained in:
Andrew Branch
2020-07-30 11:37:04 -07:00
committed by GitHub
parent faf128de15
commit 7119e2b74f
5 changed files with 85 additions and 2 deletions
+2 -2
View File
@@ -33624,7 +33624,7 @@ namespace ts {
return setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes);
}
const iteratorType = getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype);
const iteratorType = getIntersectionType(map(signatures, getReturnTypeOfSignature));
const iterationTypes = getIterationTypesOfIterator(iteratorType, resolver, errorNode) ?? noIterationTypes;
return setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes);
}
@@ -33830,7 +33830,7 @@ namespace ts {
// Resolve the *yield* and *return* types from the return type of the method (i.e. `IteratorResult`)
let yieldType: Type;
const methodReturnType = methodReturnTypes ? getUnionType(methodReturnTypes, UnionReduction.Subtype) : neverType;
const methodReturnType = methodReturnTypes ? getIntersectionType(methodReturnTypes) : neverType;
const resolvedMethodReturnType = resolver.resolveIterationType(methodReturnType, errorNode) || anyType;
const iterationTypes = getIterationTypesOfIteratorResult(resolvedMethodReturnType);
if (iterationTypes === noIterationTypes) {
+17
View File
@@ -0,0 +1,17 @@
//// [for-of58.ts]
type X = { x: 'x' };
type Y = { y: 'y' };
declare const arr: X[] & Y[];
for (const item of arr) {
item.x;
item.y;
}
//// [for-of58.js]
for (const item of arr) {
item.x;
item.y;
}
@@ -0,0 +1,29 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of58.ts ===
type X = { x: 'x' };
>X : Symbol(X, Decl(for-of58.ts, 0, 0))
>x : Symbol(x, Decl(for-of58.ts, 0, 10))
type Y = { y: 'y' };
>Y : Symbol(Y, Decl(for-of58.ts, 0, 20))
>y : Symbol(y, Decl(for-of58.ts, 1, 10))
declare const arr: X[] & Y[];
>arr : Symbol(arr, Decl(for-of58.ts, 3, 13))
>X : Symbol(X, Decl(for-of58.ts, 0, 0))
>Y : Symbol(Y, Decl(for-of58.ts, 0, 20))
for (const item of arr) {
>item : Symbol(item, Decl(for-of58.ts, 5, 10))
>arr : Symbol(arr, Decl(for-of58.ts, 3, 13))
item.x;
>item.x : Symbol(x, Decl(for-of58.ts, 0, 10))
>item : Symbol(item, Decl(for-of58.ts, 5, 10))
>x : Symbol(x, Decl(for-of58.ts, 0, 10))
item.y;
>item.y : Symbol(y, Decl(for-of58.ts, 1, 10))
>item : Symbol(item, Decl(for-of58.ts, 5, 10))
>y : Symbol(y, Decl(for-of58.ts, 1, 10))
}
+27
View File
@@ -0,0 +1,27 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of58.ts ===
type X = { x: 'x' };
>X : X
>x : "x"
type Y = { y: 'y' };
>Y : Y
>y : "y"
declare const arr: X[] & Y[];
>arr : X[] & Y[]
for (const item of arr) {
>item : X & Y
>arr : X[] & Y[]
item.x;
>item.x : "x"
>item : X & Y
>x : "x"
item.y;
>item.y : "y"
>item : X & Y
>y : "y"
}
@@ -0,0 +1,10 @@
// @target: es6
type X = { x: 'x' };
type Y = { y: 'y' };
declare const arr: X[] & Y[];
for (const item of arr) {
item.x;
item.y;
}