You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The behaviour is consistent across all versions since the introduction of logical assignment operators in TypeScript 4.0.
Checked range from 4.0.5 to Nightly, no changes in behaviour observed.
typeF=()=>number;typeR={[x: string]: R|F|undefined}constisFunc=<Textends(...args: any[])=>any>(maybe:unknown) : maybe is T=>typeofmaybe==="function";constcheck=(i: R)=>{lettmp:R=i;letcurr=tmp["something"];// R | F | undefined, expectedif(isFunc<F>(curr))return;curr// R | undefined, expectedtmp=curr||(curr={});//ok, expectedtmp=curr||={};// Type 'R | F' is not assignable to type 'R'.};
🙁 Actual behavior
Error 2322 on the second tmp assignment because R | F is not narrowed to R as with the curr || (curr = {})
🙂 Expected behavior
No error since both assignments to tmp are functionally equivalent
(I might be missing something obvious about how logical assignment is intended to work from the type system standpoint)
The text was updated successfully, but these errors were encountered:
This is a bit tricky. In curr || (curr = { }), the LHS contributes the control-flowed type of curr, and the RHS contributes { }, so no problems.
In curr ||= { }, no control-flow analysis is done on the type of curr because it's an assignment target and thus we need to allow any source assignable to the declared type.
This is in-principle fixable - we need to compute the CFA type of curr when producing the type of the resulting expression rather than using the declared type for both assignability and expression result - but might be a bit annoying to thread through the code (or might be trivial, not sure).
@RyanCavanaugh yeah, I expected the issue to lie in the control-flow analysis (well, lack thereof) in the case of logical assignment operators... Thank you for confirming this is something to consider fixing - I personally have no issue in a more verbose syntax that takes advantage of the traditional way of short-circuiting assignment but I assume the more people start using these newish operators, the higher the chances this will trip someone up.
I can try poking around to see if I can come up with a PR if you'd accept one but not sure if that is not out of my depth
Bug Report
🔎 Search Terms
logical assignment, narrowing
🕗 Version & Regression Information
The behaviour is consistent across all versions since the introduction of logical assignment operators in TypeScript 4.0.
Checked range from 4.0.5 to Nightly, no changes in behaviour observed.
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Error 2322 on the second
tmp
assignment becauseR | F
is not narrowed toR
as with thecurr || (curr = {})
🙂 Expected behavior
No error since both assignments to
tmp
are functionally equivalent(I might be missing something obvious about how logical assignment is intended to work from the type system standpoint)
The text was updated successfully, but these errors were encountered: