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
Assertions do not narrow related variables like conditions do #60904
constnum: number=1;constisNumOne=num===1;// The Assertion only narrows `isNumOne` to "true", but leaves `num` as numberfunctionassertTrue(value: boolean): asserts value is true{if(!value)throwError("not true");}assertTrue(isNumOne);isNumOne;// actual: `true`; expected: `true` ✅num;// actual: `number`; expected: `1` ❌// `If` narrows both `isNumOne` and `num`if(!(isNumOne))throwError("not true");isNumOne;// actual: `true`; expected: `true` ✅num;// actual: `1`; expected: `1` ✅
🙁 Actual behavior
In the example above, when isNumOne is narrowed to true using an assertion function assertTrue() or if, I expect num to be narrowed down to 1 at the same time because they're related.
🙂 Expected behavior
This seems only true in the case of if. assertTrue() narrows only isNumOne without narrowing num.
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.
To my understanding function assertions don't violate any of the rules from that definition. The conditional expression and the object/value are constants in this case, so they should be narrowed down, right?
The variant you have used (asserts value is true) is only used to narrow the type of the value. It doesn't try to narrow using aliased conditions. The one I mention is though and it's more natural to write it when you are looking for this kind of a logic
Activity
MartinJohns commentedon Jan 2, 2025
See #44730.
tusharsnx commentedon Jan 2, 2025
Martin Johns (@MartinJohns) Thanks for the insights.
To my understanding function assertions don't violate any of the rules from that definition. The conditional expression and the object/value are constants in this case, so they should be narrowed down, right?
Andarist commentedon Jan 2, 2025
It works OK with a different kind of assertion function:
The variant you have used (
asserts value is true) is only used to narrow the type of thevalue. It doesn't try to narrow using aliased conditions. The one I mention is though and it's more natural to write it when you are looking for this kind of a logictusharsnx commentedon Jan 3, 2025
Mateusz Burzyński (@Andarist) That made it work. Thanks.
Just curious why doesn't
asserts value is truenot work? Is it too loose to help typescript narrow the indirect references?Andarist commentedon Jan 3, 2025
It was designed to perform a different kind of narrowing. Only
asserts conditionis meant to mimic if-like behaviortusharsnx commentedon Jan 4, 2025
I see! Can
asserts value is typealso be supported just likeasserts valuefor narrowing?I'm closing the issue since
asserts valueworks for my use case.