From Discord: Issue with Optional Props in TypeScript Constructor Using '@effect/schema/Schema'
effect-bot opened this issue · comments
Summary
The discussion revolves around the behavior of optional properties in TypeScript classes when using @effect/schema/Schema
, particularly focusing on how defaults are handled during the class instantiation and the decoding phase (I -> A
).
Key points from the conversation include:
-
Optional Properties with Defaults: When using
S.optional
in conjunction with a default value (S.optional({ default: () => ... })
), there's a distinction in how these defaults apply. The expectation was that optional properties with defaults would be treated as optional in the class constructor, similar to how purely optional properties (S.optional()
) are treated. -
Decoding vs. Constructor Defaults: The discussion clarifies that there are two distinct phases where defaults can be applied:
- Decoding Phase (
I -> A
): This is where input data (I
) is transformed into the desired type (A
).withDecodingDefault
is used to apply defaults during this phase. - Constructor Phase: This is when an instance of a class is created.
withConstructorDefault
is used to apply defaults directly to the constructor.
- Decoding Phase (
-
Behavior of
default
inS.optional
: Thedefault
option inS.optional
is essentially a shortcut for applying a default during the decoding phase viaSchema.optional(...).pipe(Schema.withDecodingDefault(() => ...))
. However, this does not automatically apply defaults to the constructor phase. -
Proposal for Unified Default Handling: The conversation suggests a more intuitive approach where specifying a default for an optional property would automatically apply this default in both the decoding and constructor phases. This would simplify the handling of optional properties with defaults, making the behavior more predictable and reducing boilerplate.
-
Exception with
nullable
: An exception to the equivalence between usingdefault
inS.optional
andwithDecodingDefault
is noted when thenullable
option is involved. This specific behavior (allowingnull
to be treated as an absence of value and replaced with a default) cannot be replicated withwithDecodingDefault
alone.
Key Takeaways:
- There's a nuanced difference between how optional properties with and without defaults are treated in class constructors when using
@effect/schema/Schema
. - The library distinguishes between applying defaults during the decoding phase and directly in the constructor, with separate APIs for each.
- A proposal for a more intuitive handling of defaults suggests automatically applying specified defaults in both the decoding and constructor phases, which could enhance usability and reduce confusion.
- The handling of
null
values withnullable
anddefault
options inS.optional
introduces an exception to the general rules of default application, highlighting the complexity of default value management in schema definitions.
Discord thread
https://discord.com/channels/795981131316985866/1239701993686306918