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
functiontuple(): [null,string]|[string,null]{if(Math.random()<0.5){return[null,'a string'];}return['a string',null];}constarr=tuple();if(arr[0]===null){arr[1].toUpperCase();// <-- 👍 Works! TS knows arr[1] is a string}const[a,b]=tuple();if(a===null){b.toUpperCase();// <-- 🚨 Error! TS doesn't know b is a string}
Expected behavior:
TS can refine the destructured variables based on the function union return type.
Actual behavior:
Error.
It makes sense that when I do
const[a,b]=tuple();
That at that point, a and b need to both have an inferred type of null | string.
But when inside the conditional check if (a === null) I was expecting type refinement. Maybe that's an impossibility, but TS has gotten so smart I was genuinely surprised it wasn't able to refer that b was a string at that point.
Basically the type system doesn't track any dependencies between different variables, destructured or otherwise. When you write a type guard such as if (a === null), the compiler can only narrow the variable(s) directly involved in the guard expression, in this case a. It doesn't have any way of knowing internally what that narrowing implies for b.
It's for the same reason that the following doesn't work:
As far as I understand, tracking this kind of thing would represent a lot of added complexity in the control-flow analyzer, so TS doesn't even try to do it.
TypeScript Version: 3.5.1
Search Terms:
destructure tuple destructuring
Code
Expected behavior:
TS can refine the destructured variables based on the function union return type.
Actual behavior:
Error.
It makes sense that when I do
That at that point,
a
andb
need to both have an inferred type ofnull | string
.But when inside the conditional check
if (a === null)
I was expecting type refinement. Maybe that's an impossibility, but TS has gotten so smart I was genuinely surprised it wasn't able to refer thatb
was astring
at that point.Playground Link:
https://www.typescriptlang.org/play/#code/GYVwdgxgLglg9mABFEAHANgUwBQEoBciA2mCOugDSIDOUATjGAOYC6iAPsbQ81aeWwDeAKERjEMYImwBZAIZQAFgDo6csABM4AWzyIAPIgAMygKy5EI8dcR1MKOkhJlKiAORya9RkzcsA3KLiAL5BYnYOTh5ePL58LgHCocIQCLSIcnR0iAC8yGhYeIHCktKZdERGbDk1iPzoFlbi5UQAjCzKUHAAqqiomHQAwnLUOLiByalg6URyVABG1fkYY8Wl2J41efWNYYjznT19A8OjRUlAA
Related Issues:
maybe #28311 ?
The text was updated successfully, but these errors were encountered: