1

I'm quite new to typescript, I'd like to know how to make this function. I have something that closely resembles the following union type structure setup. Unfortunately it doesn't quite work as I'd expect. The failType below, contains properties of both NodeA and NodeB types.

I would expect both captureContentId and nodes to give me an error or al least have to compiler tell me that it can't figure out which of the four types it is supposed to be. Right now this just silently works.

Did I miss some syntax somewhere or is what I want to achieve just not possible? You can check out the code in the typescript playground here.

type Capture = {
    readonly [k: string | number]: { readonly contentId?: number; readonly nodes?: Array<IncludeNode | NodeA | NodeB> };
}

interface NodeA {
    readonly contentId?: number;
    readonly captures?: Capture;
}

interface NodeB {
    readonly contentId?: number;
    readonly captureContentId?: number;

    readonly beginCaptures?: Capture;
    readonly endCaptures?: Capture;

    readonly nodes?: Array<IncludeNode | NodeA | NodeB>;
}

interface IncludeNode {
    readonly include: UnionType;
}

interface NodeArray {
    readonly nodes: Array<IncludeNode | NodeA | NodeB>;
}

type UnionType = IncludeNode | NodeA | NodeB | NodeArray;


const aType: UnionType = {
    captures: { 1: { contentId: 5000 } },
};

const failType: UnionType = {
    contentId: 4003,
    captures: {
        1: { contentId: 3009 },
    },

    // These should not be allowed, yet they are?
    captureContentId: 4099,
    nodes: [{ include: aType }],
};
kelsny
  • 23,009
  • 3
  • 19
  • 48
Duckdoom5
  • 716
  • 7
  • 27
  • You can use the `XOR` type from the second answer – Tobias S. May 16 '22 at 16:00
  • @TobiasS. Comments say that it will not be viable for multiple constituents in the union. It's a nice exercise to make it work, though. – kelsny May 16 '22 at 16:02
  • does [this](https://tsplay.dev/mq5XJm) work for you? – Tobias S. May 16 '22 at 16:05
  • 1
    One value can match multiple members of a union. https://tsplay.dev/w2albW Nothing really wrong with that, in principle. What problems does this behavior cause you? – Alex Wayne May 16 '22 at 16:23
  • You would also have to use XOR in the array types I would imagine... This is getting out of hand; there should be some way to have a type do all the xors for us – kelsny May 16 '22 at 16:24
  • @TobiasS. I guess that would work. Though the error message you get is very unclear. But that link does answer my question. – Duckdoom5 May 16 '22 at 16:32

0 Answers0