typescriptreact-apollo

Typescript: narrowing types with destructuring


The following code errors:

type Foo = {
  a: true,
  b: null,
  c: null
} | {
  a: false,
  b: Error,
  c: null
} | {
  a: false,
  b: null,
  c: { prop: number}
}

function getFoo(): Foo {

  return { a: false, b: null, c: { prop: 5 } };

}

const { a, b, c } = getFoo();

if (!a && !b) {
  console.log(c.prop)
}

The error given is:

Object is possibly 'null'.(2531)

This makes somewhat sense, because when the result from getFoo() was destructured, the types from the larger Foo object was lost.

However, I'm trying to replicate what the Apollo React client is doing:

const { loading, error, data } = useQuery('...');

if (loading) {
  return '..';
}
if (error) {
  return '..';
}
return data.foo;

I'm having a hard time figuring out from their source how they make this work.

Is this doable in Typescript at all? My best guess is that their types might not be 100% accurate, and they say they always return data even when they don't.


Solution

  • It is not possible to have type guard between 2 variables. You can make a link between variable a and b to tell that: if a condition of a is met ==> b is something else. For Apollo React client, I think that strictNullChecks is disabled