Closed migueldamota closed 4 months ago
I am sure there is a solution to this problem. Unfortunately, I did not get the full context. Can you provide more details and example code? Maybe provide me with your previous code and I will try to rewrite it to use the new pipe
method.
Thanks for your response. Sure.
Here are some of the useForm
types which are mainly used for validation:
// this is based on valibot@0.30.0
import type * as v from "valibot";
type ValidationSchema<V> = v.ObjectSchema<Record<keyof V, v.BaseSchema>>;
interface FormConfig<Values> {
fields: Values;
validation?: ValidationSchema<Values>;
// other stuff...
}
export function useForm<V extends DefaultForm = DefaultForm>({ fields, validation, ... }: FormConfig<V>) {
// logic...
}
Values
is an object which defines the fields you want to use in the form. validation
should hold an object schema which keys are of Values
and just a pure schema like string()
or a pipe.
Here is another example code:
import * as v from "valibot";
const form = useForm({
fields: {
name: "",
email: "",
password: "",
},
// should have autocompletion for keys: name, email and password
validation: v.object({
name: v.string(),
email: v.pipe(v.string(), v.email()),
// should error because `password` is not defined
}),
});
I hope everything is clear 😄
To be honest, I don't know why TypeScript complains when using ObjectSchema
as a generic, but I found two workarounds:
import * as v from 'valibot';
type SchemaEntries<TValues> = {
[TKey in keyof TValues]: v.GenericSchema<TValues[TKey], unknown>;
};
interface FormConfig<TValues, TEntries extends SchemaEntries<TValues>> {
fields: TValues;
validation?: TEntries;
// other stuff...
}
function useForm<TValues, TEntries extends SchemaEntries<TValues>>(
config: FormConfig<TValues, TEntries>
) {
const schema = config.validation && v.object(config.validation);
// more code here...
}
const form = useForm({
fields: {
foo: 'foo',
bar: 42,
},
validation: {
foo: v.string(),
bar: v.number(),
},
});
import * as v from 'valibot';
type SchemaEntries<TValues> = {
[TKey in keyof TValues]: v.GenericSchema<TValues[TKey], unknown>;
};
interface FormConfig<TValues, TEntries extends SchemaEntries<TValues>> {
fields: TValues;
validation?: v.ObjectSchema<
TEntries,
v.ErrorMessage<v.ObjectIssue> | undefined
>;
// other stuff...
}
function useForm<TValues, TEntries extends SchemaEntries<TValues>>(
config: FormConfig<TValues, TEntries>
) {
// more code here...
}
const form = useForm({
fields: {
foo: 'foo',
bar: 42,
},
validation: v.object({
foo: v.string(),
bar: v.number(),
}),
});
It's working! Thank you so much 🙏
Hi there, I have a question about
ObjectSchema
. Is there a way to predefine keys? Because I want to build a customuseForm
hook. However, I can't find a way to type check the keys withobject()
. I already tried using a ObjectSchema with aRecord
and it worked but now I wanted to update it with the new pipe functionality and I am struggling with updating it 🥲If you have an idea on how I can do this or have any questions, please let me know.