Home > Software design >  Type narrowing using `in` not working as expected
Type narrowing using `in` not working as expected

Time:08-19

I am trying to narrow a type for TypeScript like so:

const result = await fetch('example.com')

if (typeof result === "object" && "errors" in result) {
  console.error(result.errors);
}

So just to be clear the type of result before the if should be unknown.

However my ide tells me TS2339: Property 'errors' does not exist on type 'object'.

This to me looks like TS is ignoring the in keyword. I put the typeof result === "object" there to check if I could use the in in the first place.

Strangely enough my IDE does not complain when I do this:

if (typeof result === "object" && "errors" in result) {
  console.error(result["errors"]);
}

But it seems TS just doesn't check this because I also don't get any complaints with this:

if (typeof result === "object" && "errors" in result) {
  console.error(result["nothere"]);
}

Can anyone shed some light on this for me?

CodePudding user response:

The in operator won't let you "add" a key to an existing type.

You have to explicitly tell the compiler that the key might exist :

const result: Response & { errors?: unknown } = await fetch('example.com')

if (typeof result === "object" && "errors" in result) {
    console.error(result.errors);
}

Playground

  • Related