withDefault alters S.is returned value
XVincentX opened this issue · comments
Long time no chat @gcanti!
I am using Effect-TS in Microsoft (and really every single company I have worked at and will work at) and I am having a weird behavior that I believe might be a bug.
It sounds like using withDefault
alters the return value of S.is
- and I do not know if I am doing something wrong or it is a bug.
What version of @effect/schema
is running?
0.50.0
What steps can reproduce the bug?
const S = require("@effect/schema/Schema");
const struct = S.struct({
skip: S.optional(S.array(S.string)).withDefault(() => []),
});
S.parseSync(struct)({});
// { skip: [] }
S.is(struct)({});
// false
const struct2 = S.struct({ skip: S.optional(S.array(S.string)) });
S.parseSync(struct2)({});
// {}
S.is(struct2)({});
//true
What is the expected behavior?
I would be expecting to see true
for the first part as well.
It's working as intended: applying a default is a transformation carried out by, for example, parseSync
. However, S.is
doesn't perform any transformation, it simply verifies that the input conforms to a type (in this case, { readonly skip: readonly string[]; }
).
That I understand, and I am not asking to is
to apply the transformation. What is unclear is - if skip
is optional, why is not the empty object passing the test? Why is withOptional
changing the behavior?
skip
is optional in the From
type but required in the To
type:
import * as S from "@effect/schema/Schema"
/*
const struct: S.Schema<{
readonly skip?: readonly string[]; // From type
}, {
readonly skip: readonly string[]; // To type
}>
*/
const struct = S.struct({
skip: S.optional(S.array(S.string)).withDefault(() => [])
})
and S.is
verifies the To
type as you can see from its signature
const is: <_, A>(schema: Schema.Schema<_, A>) => (a: unknown) => a is A
Oooj ok - that was my misunderstanding then. Thanks a lot for the prompt reply!!