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

FormMetadata type mismatch #406

Open
aaronadamsCA opened this issue Feb 1, 2024 · 3 comments
Open

FormMetadata type mismatch #406

aaronadamsCA opened this issue Feb 1, 2024 · 3 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@aaronadamsCA
Copy link
Contributor

aaronadamsCA commented Feb 1, 2024

Describe the bug and the expected behavior

I have a component that takes FormMetadata as a prop. The form metadata I get from useForm() is no longer compatible with the FormMetadata type.

The last working version was v1.0.0-rc.0. It looks like the problem was introduced in v1.0.0-rc.1.

Conform version

v1.0.0

Steps to Reproduce the Bug or Issue

https://stackblitz.com/edit/remix-run-remix-thrjv1?file=index.ts

Type 'FormMetadata<{ foo: string; }, string[]>' is not assignable to type 'FormMetadata'.
  Type 'FormMetadata<{ foo: string; }, string[]>' is not assignable to type '{ id: FormId<Record<string, unknown>, string[]>; context: Wrapped<FormContext<Record<string, unknown>, string[], Record<string, unknown>>>; status?: "success" | "error" | undefined; getFieldset: () => { [x: string]: FieldMetadata<unknown, Record<string, unknown>, string[]>; }; onSubmit: (event: FormEvent<HTMLFormElement>) => void; noValidate: boolean; }'.
    Types of property 'context' are incompatible.
      Type 'Wrapped<FormContext<{ foo: string; }, string[], { foo: string; }>>' is not assignable to type 'Wrapped<FormContext<Record<string, unknown>, string[], Record<string, unknown>>>'.
        Type 'FormContext<{ foo: string; }, string[], { foo: string; }>' is not assignable to type 'FormContext<Record<string, unknown>, string[], Record<string, unknown>>'.
          Type 'FormContext<{ foo: string; }, string[], { foo: string; }>' is not assignable to type '{ submit: (event: FormEvent<HTMLFormElement>) => void; onUpdate: (options: Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>) => void; }'.
            Types of property 'onUpdate' are incompatible.
              Type '(options: Partial<FormOptions<{ foo: string; }, string[], { foo: string; }>>) => void' is not assignable to type '(options: Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>) => void'.
                Types of parameters 'options' and 'options' are incompatible.
                  Type 'Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>' is not assignable to type 'Partial<FormOptions<{ foo: string; }, string[], { foo: string; }>>'.
                    Types of property 'onValidate' are incompatible.
                      Type '((context: { form: HTMLFormElement; submitter: HTMLInputElement | HTMLButtonElement | null; formData: FormData; }) => Submission<Record<string, unknown>, string[], Record<string, unknown>>) | undefined' is not assignable to type '((context: { form: HTMLFormElement; submitter: HTMLInputElement | HTMLButtonElement | null; formData: FormData; }) => Submission<{ foo: string; }, string[], { foo: string; }>) | undefined'. (2322)

What browsers are you seeing the problem on?

No response

Screenshots or Videos

No response

Additional context

I think it's possible something was missed in 465d1ba, but so far I haven't found it.

@edmundhung
Copy link
Owner

It might be because we now have a basic FormContext type and a react version FormContext. Looked at the diff from rc.0 to rc.1 a bit but still unsure what's went wrong as well.

For now, I think you can just use FormMetadata<any> since that's what it really means when you don't specify the schema there.

@edmundhung edmundhung added bug Something isn't working help wanted Extra attention is needed labels Feb 2, 2024
@aaronadamsCA
Copy link
Contributor Author

I added "noErrorTruncation": true to the StackBlitz so we can see the full TypeScript error.

On this line:

Type 'FormMetadata<{ foo: string; }, string[]>' is not assignable to type 'FormMetadata'.
  Type 'FormMetadata<{ foo: string; }, string[]>' is not assignable to type '{ id: FormId<Record<string, unknown>, string[]>; context: Wrapped<FormContext<Record<string, unknown>, string[], Record<string, unknown>>>; status?: "success" | "error" | undefined; getFieldset: () => { [x: string]: FieldMetadata<unknown, Record<string, unknown>, string[]>; }; onSubmit: (event: FormEvent<HTMLFormElement>) => void; noValidate: boolean; }'.
    Types of property 'context' are incompatible.
      Type 'Wrapped<FormContext<{ foo: string; }, string[], { foo: string; }>>' is not assignable to type 'Wrapped<FormContext<Record<string, unknown>, string[], Record<string, unknown>>>'.
        Type 'FormContext<{ foo: string; }, string[], { foo: string; }>' is not assignable to type 'FormContext<Record<string, unknown>, string[], Record<string, unknown>>'.
          Type 'FormContext<{ foo: string; }, string[], { foo: string; }>' is not assignable to type '{ submit: (event: FormEvent<HTMLFormElement>) => void; onUpdate: (options: Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>) => void; }'.
            Types of property 'onUpdate' are incompatible.
              Type '(options: Partial<FormOptions<{ foo: string; }, string[], { foo: string; }>>) => void' is not assignable to type '(options: Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>) => void'.
>>              Types of parameters 'options' and 'options' are incompatible.
                  Type 'Partial<FormOptions<Record<string, unknown>, string[], Record<string, unknown>>>' is not assignable to type 'Partial<FormOptions<{ foo: string; }, string[], { foo: string; }>>'.
                    Types of property 'onValidate' are incompatible.
                      Type '((context: { form: HTMLFormElement; submitter: HTMLInputElement | HTMLButtonElement | null; formData: FormData; }) => Submission<Record<string, unknown>, string[], Record<string, unknown>>) | undefined' is not assignable to type '((context: { form: HTMLFormElement; submitter: HTMLInputElement | HTMLButtonElement | null; formData: FormData; }) => Submission<{ foo: string; }, string[], { foo: string; }>) | undefined'. (2322)

TypeScript starts to check whether type Record<string, unknown> satisfies type { foo: string; }, which will always fail.

I vaguely understand this is due to contravariance of function types, but I don't understand why it started happening when it did, nor do I know how to solve it.

@Varkoff
Copy link

Varkoff commented Feb 9, 2024

Getting the same error with FieldMetadata, looping through an array of objects.

const Schema = z.object({
users: z.array(z.object({ name: z.string() })
})
const Component = () => {

	const list = fields.users.getFieldList();
	return (
		<div>{list.map(l => <ListItem config={l} key={l.key} />}</div>
	)
}
const ListItem = ({config}: {config: FieldMetadata<z.infer<typeof Schema>>}) => {
return null
}

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

No branches or pull requests

3 participants