ianstormtaylor / superstruct

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

Defaulted optional to undefined does not fill field with default value #1185

Open yannbriancon opened 1 year ago

yannbriancon commented 1 year ago

[BUG]

Description

Using defaulted with optional type and undefined default value creates an object without default field.

Issue comes between version 0.16.0 and version 0.16.2, almost same time another issue was fixed about optional (#1106, @cwouam)

Expected Behaviour

Defaulted optional field exists with default value to undefined.

const UserInfo = type({
  name: string(),
  age: defaulted(optional(number()), undefined)
});

const user = create(
  {
    name: "3"
  },
  UserInfo
);

/*
  * user = { 
  *     name: "3"
  *     age: undefined
  * }
  */

Actual Behaviour

Defaulted optional field does not exist.

const UserInfo = type({
  name: string(),
  age: defaulted(optional(number()), undefined)
});

const user = create(
  {
    name: "3"
  },
  UserInfo
);

/*
  * user = { 
  *     name: "3"
  *     // missing age field
  * }
  */

Reproduction

https://codesandbox.io/s/superstruct-optional-defaulted-bug-p79txr?file=/src/index.ts:478-579

Opinion

I think we could modify the behaviour to make defaulted of an optional convert to a required property.

Another way to change this without breaking would be to add another type undefined to allow for undefined type without being optional.