'Recursive discriminated unions in typescript

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?
        }
    }
}

Edit: turns out I was using codesandbox which has a linter by default that marks use before declaration as errors, and since I hadn't touched typescript in a long time I didn't figure out something fishy was going on 😅



Solution 1:[1]

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

demo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ??????? ???????????