Michal Kurz
Michal Kurz

Reputation: 2095

How to make a deep type guard?

I have the following type:

type Child = {
  foo: number | null
}

type Parent = { 
  child: Child | null
}

I want to make a type-guard that receives Parent as a parameter and determines if foo is a number... something like:

const guard = (parent: Parent): parent?.child?.foo is number => {
  return isNumber(parent?.child?.foo)
}

I want TS to be able to now infer that parent.child is not null - is this possible?

Upvotes: 2

Views: 344

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074148

You'll have to spell it out, e.g.:

const guard = (parent: Parent): parent is {child: {foo: number}} => {
    return isNumber(parent?.child?.foo);
};

You can do that with intersection types, like this:

const guard = (parent: Parent): parent is Parent & {child: Child & {foo: number;};} => {
    return isNumber(parent?.child?.foo);
};

(You can always define a type for it rather than an inline intersection.)

Playground link

Upvotes: 3

Related Questions