diff --git a/src/fields/zod-field/zodField.ts b/src/fields/zod-field/zodField.ts index 8689dc5..ef107e1 100644 --- a/src/fields/zod-field/zodField.ts +++ b/src/fields/zod-field/zodField.ts @@ -78,31 +78,43 @@ export type OptionalZodField< OptSchema extends z.Schema = ZodUndefined, > = ZodField; // for OptionalZodField we can write false to the required atom -export type ZodField< +/** + * This is an alias to ZodField, it hides the 3rd argument from type tooltip. + */ +type RequiredZodField< Schema extends z.Schema = ZodAny, OptSchema extends z.Schema = ZodUndefined, - RequiredAtom = Atom, // required field have read-only RequiredAtom -> = FieldAtom extends Atom< - infer Config +> = ZodField; + +type ExtendFieldAtom = FieldAtom extends Atom< + infer DefaultState > - ? { - optional: () => OptionalZodField; - } & Atom< - Config & { - required: RequiredAtom; - } - > + ? Atom : never; -export const zodField = < +export type ZodField< + Schema extends z.Schema = ZodAny, + OptSchema extends z.Schema = ZodUndefined, + RequiredAtom = Atom, +> = ExtendFieldAtom< + Schema["_output"] | OptSchema["_output"], + { required: RequiredAtom } +> & { + optional: () => OptionalZodField; +}; + +export function zodField< Schema extends z.Schema, OptSchema extends z.Schema = ZodUndefined, >({ schema, optionalSchema, ...config -}: ZodFieldConfig): ZodField => { - const requiredAtom = atom(true); // constant, unwritable when .optional() is not called +}: ZodFieldConfig): RequiredZodField { + /** + * Read-only atom for default zodFields which all are required. + */ + const requiredAtom = atom(true); const baseFieldAtom = fieldAtom({ validate: zodValidate( @@ -194,4 +206,4 @@ export const zodField = < zodField.debugLabel = `zodField/${config.name ?? zodField}`; return zodField; -}; +}