Skip to content

[TypeScript] arktype validators lose error type inference — field.state.meta.errors entries appear as undefined #2221

Description

@motopods

Describe the bug

When passing an arktype schema or validator as a Field validator, the resulting error objects in field.state.meta.errors are not correctly typed. In editor hover the parameter shows as (parameter) error: undefined. This prevents safe access to properties such as error.message and makes rendering error messages fragile.

Your minimal, reproducible example

No external link — reproduction code is included in the Additional context section below. You can also paste the code into the TypeScript Playground or a minimal CodeSandbox if that helps.

Steps to reproduce

  1. Create a React app using @tanstack/react-form.
  2. Add a <form.Field /> and provide validators that come from arktype (or a wrapper around arktype)
  3. Render field.state.meta.errors and inspect types in the editor / try to access error.message
  4. Observe that each error is typed as undefined/unknown in the editor and error?.message is required to avoid a type error.

Expected behavior

TypeScript should preserve the error type (including a message property) when arktype validators are used so that field.state.meta.errors entries have a useful, typed shape and consumers can safely render error.message without the editor showing the parameter as undefined.

How often does this bug happen?

No response

Screenshots or Videos

No response

Platform

  • OS: Windows
  • Browser: Edge
  • Adapter: react-form

TanStack Form adapter

react-form

TanStack Form version

v1.33.0

TypeScript version

7.0.0-dev.20260621.1

Additional context

Reproduction snippets

<form.Field
  name="name"
  validators={{
    onChange: type("string>0").describe('name is required'),
  }}
>
  {(field) => (
    <div>
      <Input
        value={field.state.value}
        onBlur={field.handleBlur}
        onChange={(e) => field.handleChange(e.target.value)}
      />
      {field.state.meta.errors.map((error) => (
        // Here editor shows: (parameter) error: undefined
        <p key={error?.description}>{error?.description}</p>
      ))}
    </div>
  )}
</form.Field>

Relevant type helper that may interact badly with callable arktype types:

type RejectPromiseValidator<T> = 
  T extends (...args: any[]) => infer R   // <-- arktype Type is callable, hits this branch
    ? 0 extends 1 & R 
      ? T 
      : [R] extends [Promise<any> | PromiseLike<any>] 
        ? never    // <-- if return is PromiseLike, becomes never
        : T 
    : T            // <-- non-callable types fall through

Notes / hypothesis:

  • arktype's schema validator types are callable and may produce complex return types (union / branded objects / PromiseLike wrappers).
  • The conditional type above (RejectPromiseValidator) uses inference and intersection-checking (0 extends 1 & R) that may trigger distributive behavior or collapse inferred types from arktype into any/unknown/never and end up erasing the resulting error shape.
  • The loss likely happens while mapping validator return types into TanStack Form's ValidationError/StandardSchemaV1Issue types and then into field.state.meta.errors.

Files to inspect that likely contain the relevant type-chaining:

  • packages/form-core/src/util-types.ts (RejectPromiseValidator)
  • packages/form-core/src/types.ts (FieldErrorMapFromValidator, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn)
  • packages/form-core/src/FieldApi.ts (FieldValidateOrFn types)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions