Home > front end >  TS complaining about undefine props even its inside an if condition
TS complaining about undefine props even its inside an if condition

Time:02-01

why TS is complaining that 'data.st' is possibly 'undefined'. in this code, even its inside the if condition.

interface Data {
  st?: number;
}

let events = [{id: 1, st: 123}, {id: 2, st: 465}];

function test(data: Data) {
  if (data.st) {
    events = events.filter(
      (ce) => ce.st >= data.st, // 'data.st' is possibly 'undefined'.
    );
  }
}

here is the playground.

CodePudding user response:

You need to create a ref to the data that you want to use and check that.

Something similar to this:

function test(data: Data) {
  const st = data.st;

  if (st) {
    events = events.filter(
      (ce) => ce.st >= st
    );
  }
}

They main reason why this TS cannot narrow here is because is actually unsound. You are passing a callback to events.filter and there is no guarantee that your callback is gonna get executed right away. There is no way (at least to my knowledge) to signal that a function will execute the callbacks provided in the same execution run. In this case we know that Array.filter does this, but from TS point of view there is no guarantee of this.

The second reason why this doesn't work is that TS cannot properly track all the references to data to figure out is some other piece of code could change data.ts between the time of the check and the time of the execution callback.

It can actually figure this out if you declare it as const and then narrow it.

The behaviour regarding callbacks can also be noticed in this case:

function test(data: Data) {
  let st = data.st;

  if (st) {
    events = events.filter(
      (ce) => ce.st >= st
    );
  }
}

You are still gonna get the same error now. The main reason is the callback call. If you check the st type before the callback you'll see that it got narrowed to number, but inside the callback it gets widened to number | undefined.

You can check the second example here

  • Related