Issue
The following is an example that reproduces the problem:
type F = () => number;
type R = {
[ x: string ]: R | F | undefined
}
const isFunc = <T extends (...args: any[]) => any>(maybe:unknown) : maybe is T => typeof maybe === "function";
const check = (i: R) => {
let tmp:R = i;
let curr = tmp["something"];
if( isFunc<F>(curr) ) return;
curr // R | undefined, expected
tmp = curr || (curr = {}); //ok, expected
tmp = curr ||= {}; //Index signature is missing in type 'F'
};
As you can see, after the type guard, curr
is correctly narrowed to R | undefined
. After that, I am reassigning tmp
to curr
and default the latter to an empty object should it be missing.
Now, if I use a good old A || A = B
approach, curr
on the left side of the logical OR is properly inferred as R | undefined
. However, if I use the logical OR assignment to make the intent clearer, curr
is inferred as R | F | undefined
. This obviously results in an error, since F
is not assignable to R
.
The question is - what would be the reason for curr
to be losing the narrowing in the second case?
Solution
After submitting this as an issue in the source repository, the behaviour is confirmed to be a bug (more like a current limitation because no control-flow analysis is done when using logical assignment operators as opposed to short-circuiting assignment with logical operators).
Answered By - Oleg Valter
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.