Skip to content

Tanstack Form custom component typings#7

Open
lewsmith wants to merge 1 commit intoakash3444:mainfrom
lewsmith:refactor/custom-component-typings
Open

Tanstack Form custom component typings#7
lewsmith wants to merge 1 commit intoakash3444:mainfrom
lewsmith:refactor/custom-component-typings

Conversation

@lewsmith
Copy link
Copy Markdown

@lewsmith lewsmith commented Oct 9, 2025

Fixes custom components not being typed correctly when passed via createFormHook

At the moment, custom components passed to createFormHook are not typed. You also have to pass the two contexts even though they are not used:

import { createFormHookContexts } from '@tanstack/react-form';
import { createFormHook } from '../ui/form-tanstack';
import { MyCustomInput } from '../components/my-custom-input';

const { fieldContext, formContext } = createFormHookContexts();

const {
  useAppForm,
} = createFormHook({
  fieldComponents: {
    MyCustomInput,
  },
  fieldContext,
  formComponents: {},
  formContext,
});

results in a TS error:

Property 'MyCustomInput' does not exist on type 'FieldApi<{ ... }, ...> & NoInfer<{ ...; }>'.ts(2339)
image

This PR removes the need to pass the contexts and allows you to optionally pass addition field and/or form components with correct typings.

Example:

import { createFormHook } from '../ui/form-tanstack';
import { MyCustomInput } from '../components/my-custom-input';

const {
  useAppForm,
} = createFormHook({
  fieldComponents: {
    MyCustomInput,
  },
});
image

Fixes custom components not being typed correctly when passed via `createFormHook`
@lewsmith
Copy link
Copy Markdown
Author

lewsmith commented Oct 9, 2025

Adding a comment as this PR isn't showing up in the Basecn repo PR list.. odd.

@vercel
Copy link
Copy Markdown

vercel bot commented Oct 9, 2025

@lewsmith is attempting to deploy a commit to the akash3444's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Overview

Greptile Summary

This PR refactors the createFormHook function in the Tanstack Form integration to properly type custom components. Previously, developers had to manually create and pass fieldContext and formContext from createFormHookContexts(), and custom components like MyCustomInput passed via fieldComponents would cause TypeScript errors. The change introduces generic type parameters (TFieldComponents and TFormComponents) to capture the shape of custom components and merges them with built-in components (Control, Label, Description, Message for fields; Item for forms). The contexts are now created at the module level and passed internally, simplifying the API while preserving type safety. This fits into the broader BaseCN component registry system, which provides reusable form primitives built on Tanstack Form and Base UI.

Important Files Changed

Changed Files
Filename Score Overview
src/registry/components/ui/form-tanstack.tsx 2/5 Added generic type parameters to createFormHook to properly type custom components, but missing import for ComponentType will cause compilation error

Confidence score: 2/5

  • This PR has critical issues that will prevent successful compilation and requires immediate attention before merging
  • Score reduced due to: (1) missing ComponentType import from React will cause TypeScript compilation failure, (2) potential runtime issues from spread order allowing custom components to override built-in ones (Control, Label, Description, Message, Item), (3) no validation that custom components match expected component signatures
  • Pay close attention to src/registry/components/ui/form-tanstack.tsx - the missing import must be added and the spread order should be reconsidered to prevent accidental override of core components

Sequence Diagram

sequenceDiagram
    participant User
    participant createFormHook
    participant createTanstackFormHook
    participant FormHook
    participant FieldComponents
    participant FormComponents

    User->>createFormHook: "Call with optional fieldComponents & formComponents"
    createFormHook->>createFormHook: "Merge custom components with defaults"
    Note over createFormHook: mergedFieldComponents = {<br/>Control, Description, Label, Message,<br/>...custom fieldComponents}
    Note over createFormHook: mergedFormComponents = {<br/>Item,<br/>...custom formComponents}
    createFormHook->>createTanstackFormHook: "Pass merged components with fieldContext & formContext"
    createTanstackFormHook->>FormHook: "Return typed form hook"
    FormHook-->>User: "Return hook with typed custom components"
    User->>FormHook: "Use form hook (e.g., useAppForm)"
    FormHook->>FieldComponents: "Access field.MyCustomInput (typed)"
    FormHook->>FormComponents: "Access form components"
    FieldComponents-->>User: "Render with correct types"
Loading

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

},
formComponents: { ...args?.formComponents, Item: FormItem },
function createFormHook<
TFieldComponents extends Record<string, ComponentType<any>> = {},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: Missing import for ComponentType. Add at the top: import type { ComponentType } from 'react';

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/registry/components/ui/form-tanstack.tsx
Line: 132:132

Comment:
**syntax:** Missing import for `ComponentType`. Add at the top: `import type { ComponentType } from 'react';`

How can I resolve this? If you propose a fix, please make it concise.

Description: FieldDescription,
Label: FieldLabel,
Message: FieldMessage,
...(args?.fieldComponents ?? ({} as TFieldComponents)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Spread order allows custom components to override built-in ones (Control, Label, etc.). Move custom components before built-ins if this is unintended. Should custom fieldComponents be able to replace the built-in Control/Label/Message/Description components?

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/registry/components/ui/form-tanstack.tsx
Line: 143:143

Comment:
**logic:** Spread order allows custom components to override built-in ones (Control, Label, etc.). Move custom components before built-ins if this is unintended. Should custom fieldComponents be able to replace the built-in Control/Label/Message/Description components?

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant