Home > Back-end >  Recursive discriminated unions in typescript
Recursive discriminated unions in typescript

Time:09-24

What would be the best way to model discriminated unions in Typescript where, ideally, one of the fields has a type that references the union itself? To give a simple example

interface Base {
    kind: string;
    someOtherCommonField?: any;
}

interface A extends Base {
    kind: "A";
    children: Base[]; // This ideally would be TheNode[], but I can't forward declare the union (can I?)
}

interface B extends Base {
    kind: "B";
    fieldB: number;
}

type TheNode = A | B;

function makeNode(): TheNode {
    return {kind: "A", children: []};
}

const a = makeNode();

if (a.kind === "A") {
    for (let c of a.children) {
        if (c.kind === "A") {
            c.children // This is an error

            // c needs a cast to A because A#children has type Base[]
            const ca = c as A;
            ca.children // This works but how can I avoid casting?
        }
    }
}

CodePudding user response:

Yes, you can forward declare a union, just as any other type

demo

  • Related