Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fieldConfig type safety for nested fields (z.object) #27

Open
elliason opened this issue Aug 25, 2023 · 2 comments
Open

fieldConfig type safety for nested fields (z.object) #27

elliason opened this issue Aug 25, 2023 · 2 comments
Labels
help wanted Extra attention is needed

Comments

@elliason
Copy link

Hi, I have been doing some experiments with this form and have come across this problem:
When I use only 1 level of fields, without any z.object in my schema, the autocomplete and type validation for fieldConfig works fine, but when I use some nested fields and objects in my schema, the autocompletion is lost.
Consider this schema:
`z.object({
group1: z.object({
username: z.string({
required_error: 'Username is required.',
}),

    password: z.string({
        required_error: 'Password is required.',
    }),
}),

});`
If I now try to put set some irrelevant property to fieldConfig, there is no warning:
image

The expected behavior would be to throw a type error, as in the flat schema case:
image

Is it because typescript is not able to correctly resolve the recursion type to FieldConfigItem ?

Also, I was wondering what approach you would recommend for extending the configuration options for the objects. I would like to be able to choose from more rendering components than just Accordion, but am not sure what is the best path to take. The best solution would be something type-safe.

Anyway, thanks for this great idea of schema based form !

@vantezzen
Copy link
Owner

I've also noticed this problem while creating the examples. In the type declarations, nested objects should be typed too but it looks like the declaration is wrong somewhere.

export type FieldConfig<SchemaType extends z.infer<z.ZodObject<any, any>>> = {
// If SchemaType.key is an object, create a nested FieldConfig, otherwise FieldConfigItem
[Key in keyof SchemaType]?: SchemaType[Key] extends object
? FieldConfig<z.infer<SchemaType[Key]>>
: FieldConfigItem;
};

As for extending, general props can be added to "AutoFormInputComponentProps" while new component types can be added to the "INPUT_COMPONENTS" object

const INPUT_COMPONENTS = {

@vantezzen vantezzen added the help wanted Extra attention is needed label Oct 13, 2023
@paradisi-davide-servizi
Copy link

paradisi-davide-servizi commented Nov 23, 2023

Hey @vantezzen! amazing library so far, found a workaround by inspecting the zod type shape instead of the inferred type, it look something like this:

export type FieldConfig<SchemaType extends z.AnyZodObject> = {
  // If SchemaType.key is an object, create a nested FieldConfig, otherwise FieldConfigItem
  [Key in keyof SchemaType["shape"]]?: SchemaType["shape"][Key] extends z.AnyZodObject ?
  FieldConfig<SchemaType["shape"][Key]> :
  FieldConfigItem;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants