Typescript discriminated union with default interface

Viewed 327

Imagine this example:

interface IBase {
    type: string;
    value: number;
}

interface IA extends IBase {
    type: "A";
    a: string;
}

interface IB extends IBase {
    type: "B";
    b: string;
}

type IObj = IA | IB;

///
const val: IObj = {} as any; // don't care the inside

if (val.type === "A") {
    // val is IA (val.a exsits)
}

if (val.type === "B") {
    // val is IB (val.b exsits)
}

But, what happens if I want the "IBase" as "default" interface. For example:

if (val.type === "XYZ") {
    // val must be "IBase"
}

I tried IBase to the IObj but:

type IObj = IA | IB | IBase;

//
const val: IObj = {} as any; // don't care the inside

if (val.type === "A") {
    // val is "IA | IBase" (val.a not exists)
}

if (val.type === "B") {
    // val is "IB | IBase" (val.b not exists)
}

if (val.type === "XYZ") {
    // val is IBase
}

So, Is there a way to make a default interface using discriminated union?

1 Answers

You could use type guards to such checks. They are used to determine does a value conform to specific interface:

const val: IObj = {} as any;

function isIA(arg: IObj): arg is IA {
    return arg.type === "A";
}

if (isIA(val)) {
  // here val conforms to IA interface.
}
Related