Have this code
type IUnionType = IMulti | ISingle;
function isMulti(q: IUnionType): q is IMulti {
return 'ans' in q;
}
//this code is no errors
if (isMulti(o.q[0])) {
o.q[0].ans= []; // this case TS know that o.q[0] is IMulti
}
//this code have error Property 'ans' does not exist on type 'IUnionType'.
Property 'ans' does not exist on type 'ISingle'
var z = 1;
if (isMulti(o.q[z])) {
o.q[z].ans= []; // this case TS DONOT KNOW that o.q[0] is IMulti
}
Difference between code is that i access o.q by index in var z.
Why is have TS error in second case? same error i have if i iterate o.q in for loop
Have this code
type IUnionType = IMulti | ISingle;
function isMulti(q: IUnionType): q is IMulti {
return 'ans' in q;
}
//this code is no errors
if (isMulti(o.q[0])) {
o.q[0].ans= []; // this case TS know that o.q[0] is IMulti
}
//this code have error Property 'ans' does not exist on type 'IUnionType'.
Property 'ans' does not exist on type 'ISingle'
var z = 1;
if (isMulti(o.q[z])) {
o.q[z].ans= []; // this case TS DONOT KNOW that o.q[0] is IMulti
}
Difference between code is that i access o.q by index in var z.
Why is have TS error in second case? same error i have if i iterate o.q in for loop
Share Improve this question asked yesterday Andrew MAndrew M 173 bronze badges 5 |1 Answer
Reset to default 0TS doesn't support scoping of var
in narrowing, just use let
. Overall using var
is a very bad idea nowadays, very bug prone, for example no conflict of variables with the same name. FOr loops use an intermediate variable if needed:
function zzz(o: {q:IUnionType[]}){
let idx = 1;
if (isMulti(o.q[idx])) {
o.q[idx].ans= [];
}
for(let i=0;i<o.q.length;i++){
const item = o.q[i];
if (isMulti(item)) {
item.ans= []; // this case TS know that o.q[0] is IMulti
}
}
for(const item of o.q){
if (isMulti(item)) {
item.ans= []; // this case TS know that o.q[0] is IMulti
}
}
}
IMulti
andISingle
are – jcalz Commented yesterday0
is constant. Withvar z
, TS doesn't try to track it becausevar
scope is weird. You can makez
aconst
or alet
for it to work. Does that fully address the q? If so I'll write an a. – jcalz Commented yesterdayz
is constant. It treatso.q[z]
as an indexed access expression with an unknown, potentially changing key and doesn't apply narrowing. This should be fixed with thelet
keyword – Oluwafemi Sule Commented 12 hours ago