diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c61581facde83..215c8d82aaaae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28838,8 +28838,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated // type of T. function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined { + const hasIterable = getGlobalIterableType(/* reportErrors */ false) !== emptyGenericType; return arrayContextualType && ( - getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String) + getTypeOfPropertyOfContextualType(filterType(arrayContextualType, t => isArrayOrTupleLikeType(t) || !!getIndexTypeOfType(t, numberType) || hasIterable && isTypeAssignableTo(t, createIterableType(anyType))), "" + index as __String) || mapType( arrayContextualType, t => getIteratedTypeOrElementType(IterationUse.Element, t, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false), diff --git a/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.symbols b/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.symbols new file mode 100644 index 0000000000000..7a10411bfa84b --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts === +// repro from #52588 + +declare function test( +>test : Symbol(test, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 0, 0)) + + arg: Record void> | Array<(arg: number) => void> +>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 2, 22)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 3, 23)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 3, 54)) + +): void; + +test([ +>test : Symbol(test, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 0, 0)) + + (arg) => { +>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 7, 3)) + + arg; // number +>arg : Symbol(arg, Decl(contextualSignatureInArrayElementPrefersArrayUnionMember.ts, 7, 3)) + + }, +]); + diff --git a/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.types b/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.types new file mode 100644 index 0000000000000..46c74beb9459d --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInArrayElementPrefersArrayUnionMember.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts === +// repro from #52588 + +declare function test( +>test : (arg: Record void> | ((arg: number) => void)[]) => void + + arg: Record void> | Array<(arg: number) => void> +>arg : Record void> | ((arg: number) => void)[] +>arg : string +>arg : number + +): void; + +test([ +>test([ (arg) => { arg; // number },]) : void +>test : (arg: Record void> | ((arg: number) => void)[]) => void +>[ (arg) => { arg; // number },] : ((arg: number) => void)[] + + (arg) => { +>(arg) => { arg; // number } : (arg: number) => void +>arg : number + + arg; // number +>arg : number + + }, +]); + diff --git a/tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts b/tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts new file mode 100644 index 0000000000000..2af3c0735fcdd --- /dev/null +++ b/tests/cases/compiler/contextualSignatureInArrayElementPrefersArrayUnionMember.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +// repro from #52588 + +declare function test( + arg: Record void> | Array<(arg: number) => void> +): void; + +test([ + (arg) => { + arg; // number + }, +]);