ianstormtaylor / superstruct

A simple and composable way to validate data in JavaScript (and TypeScript).
https://docs.superstructjs.org
MIT License
6.94k stars 224 forks source link

assign breaks coercion #791

Open pbarbiero opened 3 years ago

pbarbiero commented 3 years ago

Wrapping a struct using defaulted with assign causes coercion to no longer work.

Easy enough test:

const struct = defaulted(
  object({
    id: string(),
    enabled: boolean(),
  }),
  {
    enabled: false,
  },
);

console.log(struct.coercer()); // { enabled: false }
console.log(assign(struct).coercer()); // undefined

Expected result: coercer still works

pbarbiero commented 3 years ago

@ianstormtaylor I am not a TS developer, and this is probably less elegant than you'd like, but this does resolve it for me:

// https://github.com/ianstormtaylor/superstruct/blob/main/src/structs/utilities.ts#L55
function assign(...Structs) {
  const isType = Structs[0].type === 'type';
  const schemas = Structs.map(s => s.schema);
  const coercers = Structs.map(s => s.coercer);
  const schema = Object.assign({}, ...schemas);
  const mergedSchema = isType ? type(schema) : object(schema);
  mergedSchema.coercer = (...args) => ({
    ...Object.assign({}, ...coercers.map(coercer => coercer(...args))),
  });
  return mergedSchema;
}