Describe does not work well with union types

Author: BoveFabioCreated Apr 25, 2024Updated Sep 20, 2024

Hi everyone,

I stumbled across a seemingly simple example where Describe does not work well with union. However, it might be I am missing something.

Consider the following:

typescript
type A = {
    a: "a";
};
type B = {
    b: "b";
};

const aStruct: Describe<A> = object({
    a: literal("a"),
});
const bStruct: Describe<B> = object({
    b: literal("b"),
});
const aorbStruct: Describe<A | B> = union([aStruct, bStruct]);

I would expect this to work. However, aorbStruct shows a TS error:

TS2322: Type Struct<A | B, null> is not assignable to type Describe<A | B>
  Types of property schema are incompatible. 
    Type null is not assignable to type
      {
        a: Describe<"a">; 
      } | {
        b: Describe<"b">;
      }

The strange thing is that it works once I include a primitive in the union:

typescript
const AorBorNumberStruct: Describe<A | B | number> = union([aStruct, bStruct, number()]);

works fine.

Could you please

  • either help me out and show me how to get the const aorbStruct: Describe<A | B> = union([aStruct, bStruct]); case working
  • or confirm that this is bug?

Thank you!

Source: ianstormtaylor/superstruct