superstruct icon indicating copy to clipboard operation
superstruct copied to clipboard

Coercion doesn't work with intersection + union (cryptic error)

Open ArturBaybulatov opened this issue 3 years ago • 0 comments

Example:

const BaseUser = type({
  id: string(),
  username: string(),
});

const Climber = type({
  type: literal('climber'),
  height: coerce(number(), string(), str => {
    if (str.trim() !== '' && Number.isFinite(Number(str))) {
      return Number(str);
    }

    throw new Error('A real number or a numeric string expected');
  }),
});

const Fighter = type({
  type: literal('fighter'),
  strength: number(),
});

const Runner = type({
  type: literal('runner'),
  speed: number(),
});

const User = intersection([BaseUser, union([Climber, Fighter, Runner])]);

const rawUser: unknown = {
  id: '1',
  username: 'john.doe',
  type: 'climber',
  height: '123',
};

const user = create(rawUser, User);
// => StructError: Expected the value to satisfy a union of `type | type | type`, but received: [object Object]

Reproduction: https://codesandbox.io/s/delicate-lake-04osw?file=/src/index.ts

ArturBaybulatov avatar Oct 06 '21 10:10 ArturBaybulatov