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
{{ message }}
Repository navigation
Type validations do not carry over when assigned to a const #48891
typeObj={test1?: stringtest2: string|nulltest3: string|false}constobj: Obj={test1: "hello",test2: "hello",test3: "hello",}functionfn(arg: string){/** blah */}// A - ✓ // expected: errorfn(obj.test1)fn(obj.test2)fn(obj.test3)// B - ✓// expected: no errorif(!!obj.test1)fn(obj.test1)if(!!obj.test2)fn(obj.test2)if(!!obj.test3)fn(obj.test3)// C - ✓ // expected: no errorif(typeofobj.test1==="string")fn(obj.test1)if(typeofobj.test2==="string")fn(obj.test2)if(typeofobj.test3==="string")fn(obj.test3)// D - x// expected: no error// behavior: errorconstok1=!!obj.test1constok2=!!obj.test2constok3=!!obj.test3if(ok1)fn(obj.test1)if(ok2)fn(obj.test2)if(ok3)fn(obj.test3)// E - x// expected: no error// behavior: errorconstok4=typeofobj.test1==="string"constok5=typeofobj.test2==="string"constok6=typeofobj.test3==="string"if(ok4)fn(obj.test1)if(ok5)fn(obj.test2)if(ok6)fn(obj.test3)
🙁 Actual behavior
TypeScript can tell when the value of a variable is not falsy inside of an if block where the validation is directly used as the condition. But it fails to carry it over when the outcome of the validation is assigned to a const and that variable is used as the condition of the if statement instead.
🙂 Expected behavior
As long as the outcome of the validation is assigned to a const, TypeScript should deduce that the value is not falsy.
Narrowing through indirect references occurs only when the conditional expression or discriminant property access is declared in a const variable declaration with no type annotation, and the reference being narrowed is a const variable, a readonly property, or a parameter for which there are no assignments in the function body.
In my code sample above, could you help me understand why there are errors in D and E when the expression is assigned to a const and obj is also const (and not re-assigned) ?
Activity
MartinJohns commentedon Apr 30, 2022
It's working as intended. See #44730.
oguzgelal commentedon Apr 30, 2022
Martin Johns (@MartinJohns) Thanks for pointing out the PR! Exactly the issue I'm facing.
In my code sample above, could you help me understand why there are errors in D and E when the expression is assigned to a
constandobjis also const (and not re-assigned) ?MartinJohns commentedon Apr 30, 2022
Because of this part:
obj.test1(and the other two) don't refer to aconstvariable, areadonlyproperty or a parameter.oguzgelal commentedon Apr 30, 2022
Ah I see! Got it. Thank you very much!
For reference, making
ObjtypeReadonlysolved the issue.