TanStackT
TanStack3mo ago
15 replies
foolish-indigo

Union type issues using `withForm`

I almost got the pattern I like working, it works in runtime. But can't fix a few couple of type issues I'm running into

I have a Contact domain that has a create/patch endpoint

I'm trying to create a shared component ContactFormFields that can be used in both the create and patch contexts. I can check in runtime if we are doing a create or patch and render conditionally

These are my types

import type { MergeExclusive, RequiredDeep } from 'type-fest'

export type EditType = ContactType & ContactPatchType // ContactType has readonly properties like `id`, ContactPatchType has the properties that are editable
export type CreateType = RequiredDeep<ContactDataType> // ContactDataType contains properties that are used for initial create, so no `id` for example
type EitherType = MergeExclusive<CreateType, EditType>


The shared component
export const ContactFormFields = withForm({
    // These values are only used for type-checking, and are not used at runtime
    // This allows you to `...formOpts` from `formOptions` without needing to redeclare the options
    defaultValues: {} as EitherType,
    props: {} as { type: 'create' | 'patch' },
    render: function Render({ form, type }) {
...


My edit form - https://pastes.io/react-contactviewform-with-patch-form-type-error-comment

And there is a similar create form(leaving out cause this is getting too long for Discord)

I have 2 problems

Problem 1
In my edit and create forms I get a type error passing
form
to ContactFormFields (this is for <ContactFormFields type="patch" form={form} />)
https://pastes.io/type-mismatches-for-formasyncvalidateorfn-and-formvalidateasyncfn


Problem 2
In the ContactFormFields
<form.AppField name="id">
  //Would expect a type error here, type should be `string | undefined`, since `id` should only be defined if we are in a `patch` context. But the type is `string` currently!
  {(field) => <div>ID: {field.state.value.length}</div>}
</form.AppField>
Was this page helpful?