TypeScript Version: 3.5.2 (it works with 3.4.4). Also tested on 3.6.0-dev.20190622
Search Terms:
Code (not real-life, just a repro)
const actions = ['resizeTo', 'resizeBy'] as const;
for (const action of actions) {
window[action] = (x, y) => {
window[action](x, y);
}
}
Expected behavior:
x and y are of type number (like in 3.4)
Actual behavior:
x and y are of type any
Playground Link: (enable noImplicitAny, but it seems to be on 3.4)
https://www.typescriptlang.org/play/#src=%0D%0Aconst%20actions%20%3D%20%5B'resizeTo'%2C%20'resizeBy'%5D%20as%20const%3B%0D%0Afor%20(const%20action%20of%20actions)%20%7B%0D%0A%09window%5Baction%5D%20%3D%20(x%2C%20y)%20%3D%3E%20%7B%0D%0A%09%09window%5Baction%5D(x%2C%20y)%3B%0D%0A%09%7D%0D%0A%7D
Related Issues:
This is probably due to https://github.com/microsoft/TypeScript/pull/30769
But the types of window.resizeTo and window.resizeBy are identical so there shouldn't be any difference or ambiguity.
You can find a real-life example here: https://github.com/sindresorhus/refined-github/pull/2164
Yes, this is caused by #30769. When an indexed access type occurs on the target side of an assignment, we form an intersection instead of a union. When intersecting properties of the same type we just end up with a property of that type, however we don't remove duplicate call/construct signatures. So, in your example the intersection ends up being a type with two (identical) call signatures, at which point we no longer do contextual typing of parameters.
We can fix the issue by removing duplicate call/construct signatures in an intersection.

Great!
I can confirm that this was fixed and works as expected in 3.6.0-dev.20190701
Thank you!
Most helpful comment
Great!