typescripttype-narrowing

Is type narrowing possible based on a function's return value?


I'm trying to achieve type narrowing that's based on a function's return value rather than a property.

The basic way to narrow based on a field works like this:

interface AFoo {
    type: "A"
    specificA();
}

interface BFoo {
    type: "B"
}

var a: AFoo | BFoo = null as any;

if (a.type === 'A') {
    a.specificA();
}

And this works like a charm, based on the union type and type's value, TS knows how to narrow the type of the object inside the conditional.

I'm trying to do something supposedly similar, like this:

interface AFoo {
    getType(): "A";
    specificA();
}

interface BFoo {
    getType(): "B";
}

var a: AFoo | BFoo = null as any;

if (a.getType() === 'A') {
    a.specificA();
}

Weirdly enough, TS is smart enough to offer auto-correct and know that getType() returns "A" or "B", but the type narrowing isn't kicking in, and a is still of type AFoo | BFoo inside the conditional statement.

Am I missing something here?

As a side note: I can't change the getType() to a field since it's actually a Java class passed into a JS environment.


Solution

  • As @jcalz wrote, it's not a feature of TS unfortunately, I had to work with a BE developer to change the Java code (which wasn't optimal).

    Thanks to everyone who helped!