Skip to content

Commit 8ebc95f

Browse files
committed
Filter out non-array types when contextually typing union members
1 parent bbfb9ac commit 8ebc95f

4 files changed

+71
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28838,8 +28838,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2883828838
// it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
2883928839
// type of T.
2884028840
function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined {
28841+
const hasIterable = getGlobalIterableType(/* reportErrors */ false) !== emptyGenericType;
2884128842
return arrayContextualType && (
28842-
getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String)
28843+
getTypeOfPropertyOfContextualType(filterType(arrayContextualType, t => isArrayOrTupleLikeType(t) || !!getIndexTypeOfType(t, numberType) || hasIterable && isTypeAssignableTo(t, createIterableType(anyType))), "" + index as __String)
2884328844
|| mapType(
2884428845
arrayContextualType,
2884528846
t => getIteratedTypeOrElementType(IterationUse.Element, t, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts ===
2+
// repro from #52588
3+
4+
declare function test(
5+
>test : Symbol(test, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 0, 0))
6+
7+
arg: Record<string, (arg: string) => void> | Array<(arg: number) => void>
8+
>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 2, 22))
9+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
10+
>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 3, 23))
11+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
12+
>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 3, 54))
13+
14+
): void;
15+
16+
test([
17+
>test : Symbol(test, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 0, 0))
18+
19+
(arg) => {
20+
>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 7, 3))
21+
22+
arg; // number
23+
>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 7, 3))
24+
25+
},
26+
]);
27+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts ===
2+
// repro from #52588
3+
4+
declare function test(
5+
>test : (arg: Record<string, (arg: string) => void> | ((arg: number) => void)[]) => void
6+
7+
arg: Record<string, (arg: string) => void> | Array<(arg: number) => void>
8+
>arg : Record<string, (arg: string) => void> | ((arg: number) => void)[]
9+
>arg : string
10+
>arg : number
11+
12+
): void;
13+
14+
test([
15+
>test([ (arg) => { arg; // number },]) : void
16+
>test : (arg: Record<string, (arg: string) => void> | ((arg: number) => void)[]) => void
17+
>[ (arg) => { arg; // number },] : ((arg: number) => void)[]
18+
19+
(arg) => {
20+
>(arg) => { arg; // number } : (arg: number) => void
21+
>arg : number
22+
23+
arg; // number
24+
>arg : number
25+
26+
},
27+
]);
28+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// repro from #52588
5+
6+
declare function test(
7+
arg: Record<string, (arg: string) => void> | Array<(arg: number) => void>
8+
): void;
9+
10+
test([
11+
(arg) => {
12+
arg; // number
13+
},
14+
]);

0 commit comments

Comments
 (0)