Handling Nullable Fields in Effect Schema with React Hook Form
Effect Schema + react-hook-form Compatibility Issue Or... I'm lost again 
Problem: When using Effect Schema with
Current Workaround: Using
I'm using
This creates the correct behavior for database operations (NULL
undefined conversion), but causes type incompatibility with
What I've Tried:
1. Custom transformation - Created
2. No optional wrapper - Using just the transformation without
3. Different transformation approaches - Various attempts at Schema.transform and Schema.propertySignature, but the fundamental issue remains: the form resolver looks at the Encoded type which retains null.
Why These Failed:
- The effectTsResolver uses the Encoded type of the schema, not the decoded Type
- Any approach that keeps
- Removing
- The type system correctly identifies that
Question:
Is there a recommended pattern for this use case?
Problem: When using Effect Schema with
optionalWith({ nullable: true }) for database fields that can be NULL, the types become incompatible with react-hook-form's resolver.Current Workaround: Using
as any type assertions in HealthScreeningForm.tsx (lines 89 and 196) with biome-ignore comments.I'm using
@effect/sql-drizzle with PostgreSQL where optional fields are stored as NULL in the database. My schema uses Schema.optionalWith({ nullable: true }) to handle these nullable fields:This creates the correct behavior for database operations (NULL
@hookform/resolvers/effect-ts. The resolver sees the Encoded type which includes null, but react-hook-form expects only boolean | undefined for optional fields.What I've Tried:
1. Custom transformation - Created
UndefinedFromNull helper that transforms T | null to T | undefined, but wrapping with Schema.optional() re-introduces the null type in the Encoded side.2. No optional wrapper - Using just the transformation without
Schema.optional() makes all fields required in the struct (even though they can be undefined).3. Different transformation approaches - Various attempts at Schema.transform and Schema.propertySignature, but the fundamental issue remains: the form resolver looks at the Encoded type which retains null.
Why These Failed:
- The effectTsResolver uses the Encoded type of the schema, not the decoded Type
- Any approach that keeps
null in the Encoded type breaks react-hook-form- Removing
Schema.optional makes fields required in TypeScript even when undefined- The type system correctly identifies that
boolean | null | undefined is not assignable to boolean | undefinedQuestion:
Is there a recommended pattern for this use case?
