Open 3pleFly opened 2 months ago
I can also confirm the same issue updating to TS 5.5
Suddenly have errors across the application from otherwise perfectly functional forms.
In my case, the required functionality is to allow null as a starting value for a field, but require a value at submission time. Previously I would use this approach as it contained all logic within the field definition :
z.object({
Field1: z
.enum(Field1Options)
.nullable()
.refine((value) => value !== null, {
message: "Please select an option",
}),
})
Now. Ts warns that null is not a valid default value as the infered schema no longer includes null.
The workaround now is to move all refines to the form-level, so would be:
z.object({
Field1: z
.enum(Field1Options)
.nullable()
})
.refine((values) => values.Field1!== null, {
path: ["Field1"],
message: "Please select an option",
})
Was my previous method just bad practice? It seems more confusing to chuck all that logic at the end now.
EDIT: Also using strict mode
I can also confirm the same issue updating to TS 5.5
Suddenly have errors across the application from otherwise perfectly functional forms.
In my case, the required functionality is to allow null as a starting value for a field, but require a value at submission time. Previously I would use this approach as it contained all logic within the field definition :
z.object({ Field1: z .enum(Field1Options) .nullable() .refine((value) => value !== null, { message: "Please select an option", }), })
Now. Ts warns that null is not a valid default value as the infered schema no longer includes null.
The workaround now is to move all refines to the form-level, so would be:
z.object({ Field1: z .enum(Field1Options) .nullable() }) .refine((values) => values.Field1!== null, { path: ["Field1"], message: "Please select an option", })
Was my previous method just bad practice? It seems more confusing to chuck all that logic at the end now.
EDIT: Also using strict mode
You can also use the boolean constructor as I've demonstrated in my post. highly appreciate your commentary :)
Hello. I don't quite understand what happens but when I use typescript 5.5 (does not happen with 5.2)the refine removes null from union in my schema. Proof:![image](https://github.com/colinhacks/zod/assets/67366321/d55703f8-7933-4e2e-822b-b0f3c5ca8cc9)
If I remove the refine segment, now null is added to the type union and the error is gone.![image](https://github.com/colinhacks/zod/assets/67366321/d496ada0-5f5e-425d-a2f6-5b61a0710f5d)
If I switch the refine function arguement with a boolean constructor,then the error is gone, but that is because typescript does not use Boolean as a type predicate, so perhaps this further proves that ts's 5.5 inferred predicates work on refine now too.![image](https://github.com/colinhacks/zod/assets/67366321/fff86e67-4a8b-4f0a-a20f-ff8e8a4f1bd6)
So obviously refine is doing something here... But, I am unable to duplicate this error when I upload it on stackblitz, here - https://stackblitz.com/edit/typescript-ebur5x?file=index.ts
I am not sure what is going on... Why is refine suddenly removing nulls from the union? it doesn't do it in older typescript versions, and I can't seem to replicate this in stackblitz so maybe it's just me? I guess the question is why is refine removing the null from my union and how can I make it stop... I am using strict mode.