diff --git a/.changeset/forty-eyes-fall.md b/.changeset/forty-eyes-fall.md new file mode 100644 index 0000000000..332b624849 --- /dev/null +++ b/.changeset/forty-eyes-fall.md @@ -0,0 +1,16 @@ +--- +'@tanstack/angular-form': patch +'@tanstack/preact-form': patch +'@tanstack/svelte-form': patch +'@tanstack/react-form': patch +'@tanstack/solid-form': patch +'@tanstack/form-core': patch +'@tanstack/lit-form': patch +'@tanstack/vue-form': patch +--- + +Refactor: Form option types are now no longer adapter-specific + +Fix: `formOptions.looseSchema`/`strictSchema` now error on missing schema + +Fix: `formOptions.looseSchema` now accepts optional `defaultValues` props diff --git a/packages/angular-form/src/form-type.ts b/packages/angular-form/src/form-type.ts index be6e3f52d4..0cb7c8f4c7 100644 --- a/packages/angular-form/src/form-type.ts +++ b/packages/angular-form/src/form-type.ts @@ -58,7 +58,8 @@ export type AngularFormType = TOptions extends FormOptions< infer TFormData, infer TFormValidators, - infer TSubmitReturn + infer TSubmitReturn, + unknown > ? InternalFormApi< TFormData, diff --git a/packages/angular-form/src/inject-form.ts b/packages/angular-form/src/inject-form.ts index f1d478b71d..10a98532f5 100644 --- a/packages/angular-form/src/inject-form.ts +++ b/packages/angular-form/src/inject-form.ts @@ -39,7 +39,7 @@ export function injectForm< TFormData, const TFormValidators extends FormValidators, TSubmitReturn, ->(options: FormOptions) { +>(options: FormOptions) { const form = new InternalFormApi( options, ) diff --git a/packages/form-core/src/FormApi/FormApi.lib.ts b/packages/form-core/src/FormApi/FormApi.lib.ts index 6af4ff0afc..8a85757888 100644 --- a/packages/form-core/src/FormApi/FormApi.lib.ts +++ b/packages/form-core/src/FormApi/FormApi.lib.ts @@ -154,7 +154,7 @@ type InternalFormOptions< TFormData, TFormValidators extends FormValidators, TSubmitReturn, -> = FormOptions & { +> = FormOptions & { formId: string } @@ -299,7 +299,7 @@ export class InternalFormApi< } constructor( - options: FormOptions, + options: FormOptions, defaultOptions?: DefaultOptions, ) { this._defaultOptions = defaultOptions @@ -415,7 +415,7 @@ export class InternalFormApi< this._notifyFormListener('reset', null) } - _update(options: FormOptions) { + _update(options: FormOptions) { const resolvedOptions = resolveDefaultOptions( options, this._defaultOptions?.form, diff --git a/packages/form-core/src/FormApi/FormApi.public.ts b/packages/form-core/src/FormApi/FormApi.public.ts index 06812a3770..be78ba7b74 100644 --- a/packages/form-core/src/FormApi/FormApi.public.ts +++ b/packages/form-core/src/FormApi/FormApi.public.ts @@ -170,6 +170,29 @@ export interface FormSubmitContext< parseIssues: ParseSubmitIssuesFn } +/** + * Handles a form submission after submission validation succeeds. + * + * A returned promise is awaited before submission finishes. Return an error + * created by the submission context's `createValidationError` or `parseIssues` + * helper to mark the submission as invalid. + * + * @typeParam TFormData - Library-managed. Do not specify explicitly. + * @typeParam TFormValidators - Library-managed. Do not specify explicitly. + * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. + */ +export type FormSubmitFn< + in out TFormData, + in out TFormValidators extends FormValidators, + in out TSubmitReturn, +> = ( + context: FormSubmitContext< + TFormData, + ToFormSchemaOutputs, + ToFormErrorTypes + >, +) => TSubmitReturn + /** * Context passed to `onSubmitInvalid` when a submission fails. * @@ -204,7 +227,9 @@ export interface FormSubmitInvalidContext< * Use this alias only when reusable code does not need type-safe access to * values, validators, or submission results. */ -export type AnyFormOptions = FormOptions +export type AnyFormOptions = FormOptions + +declare const formOptionsComponentsSymbol: unique symbol /** * Configures initial values, validation, listeners, and submission. @@ -226,12 +251,15 @@ export type AnyFormOptions = FormOptions * @typeParam TFormData - Library-managed. Do not specify explicitly. * @typeParam TFormValidators - Library-managed. Do not specify explicitly. * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. + * @typeParam TComponents - Library-managed. Do not specify explicitly. */ export interface FormOptions< in out TFormData, in out TFormValidators extends FormValidators, in out TSubmitReturn, + out TComponents, > { + readonly [formOptionsComponentsSymbol]?: TComponents /** * A stable identifier for this form. * @@ -352,13 +380,7 @@ export interface FormOptions< * } * ``` */ - onSubmit?: ( - context: FormSubmitContext< - TFormData, - ToFormSchemaOutputs, - ToFormErrorTypes - >, - ) => TSubmitReturn + onSubmit?: FormSubmitFn /** * Called after an invalid submission is detected. * diff --git a/packages/form-core/src/defaultOptions.public.ts b/packages/form-core/src/defaultOptions.public.ts index 4565b6e651..9b15646deb 100644 --- a/packages/form-core/src/defaultOptions.public.ts +++ b/packages/form-core/src/defaultOptions.public.ts @@ -56,7 +56,7 @@ interface DefaultListenersMergeOptions { * ``` */ export type DefaultFormOptions = Pick< - FormOptions, unknown>, + FormOptions, unknown, unknown>, 'errorVisibility' | 'listeners' | 'onSubmitInvalid' > & DefaultListenersMergeOptions diff --git a/packages/form-core/src/ssr.lib.ts b/packages/form-core/src/ssr.lib.ts index d2d1c85085..d401a8852d 100644 --- a/packages/form-core/src/ssr.lib.ts +++ b/packages/form-core/src/ssr.lib.ts @@ -118,7 +118,7 @@ export async function validateServerValues< const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, values: TFormData, ): Promise> { const pipeline = options.validators diff --git a/packages/form-core/src/ssr.public.ts b/packages/form-core/src/ssr.public.ts index 6f5f91cf3c..4cfef40fa9 100644 --- a/packages/form-core/src/ssr.public.ts +++ b/packages/form-core/src/ssr.public.ts @@ -29,14 +29,14 @@ export function serverValidateHelper< } } -interface ServerStateValidationResult { +interface ServerStateValidationResult { validatorIndex: number result: TResult schemaResult: unknown | null hasSchemaResult?: boolean } -interface ServerFormStateByResult { +interface ServerFormStateByResult { values: TFormData | undefined validationResults: Array> submissionAttempts: number @@ -82,7 +82,7 @@ type ServerValidateFrameworkCreateServerValidate = < const TFormValidators extends FormValidators, TSubmitReturn, >( - formOptions: FormOptions, + formOptions: FormOptions, pluginOptions?: any, ) => unknown diff --git a/packages/form-core/src/utils.public.ts b/packages/form-core/src/utils.public.ts index cb97894979..22ccdc1c07 100644 --- a/packages/form-core/src/utils.public.ts +++ b/packages/form-core/src/utils.public.ts @@ -1,4 +1,5 @@ import type { FormOptions } from './FormApi/FormApi.public' +import type { StandardSchemaV1 } from './standardSchema.public' import type { FormValidators } from './validation.public' type Primitive = string | number | boolean | bigint | symbol | null | undefined @@ -14,7 +15,7 @@ export type Editable = T extends BuiltInType : T | null | undefined type EditableObject = { - [K in keyof T]: Editable + [K in keyof T]?: Editable } export type InferUnion = TBase extends BuiltInType @@ -50,6 +51,40 @@ export type FormValidatorData> = export type NullableSchemaData> = Editable> +type FormValidatorsWithStandardSchema< + TFormValidators extends FormValidators, +> = + Extract< + TFormValidators[number], + { readonly run: StandardSchemaV1 } + > extends never + ? never + : TFormValidators + +/** + * Form options accepted by a schema mode when `validators` is statically known + * to contain at least one Standard Schema. + * + * Empty and callback-only validator collections are rejected because they + * cannot provide schema-owned form data inference. Application code normally + * receives this type through `formOptions.strictSchema`, + * `formOptions.looseSchema`, or an equivalent `appFormOptions` method rather + * than naming it directly. + * + * @typeParam TFormData - Library-managed. Do not specify explicitly. + * @typeParam TFormValidators - Library-managed. Do not specify explicitly. + * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. + * @typeParam TComponents - Library-managed. Do not specify explicitly. + */ +export type StandardSchemaFormOptions< + TFormData, + TFormValidators extends FormValidators, + TSubmitReturn, + TComponents, +> = FormOptions & { + validators: FormValidatorsWithStandardSchema +} + /** * Infers the form data type from a Standard Schema validator and requires * `defaultValues` to match the schema input. @@ -61,14 +96,13 @@ export type NullableSchemaData> = * At runtime, this returns the original options object and does not run the * schema. * - * Include the schema in `validators` to provide the type inference and - * perform validation. + * `validators` must contain at least one Standard Schema to provide the type + * inference and perform validation. * * @remarks - * **Important:** Although this returns the original object unchanged at - * runtime, its type is normalized to `FormOptions`. Optional properties such - * as `validators` therefore remain optional even when supplied. This - * tradeoff enables safer inference and reuse. + * **Important:** Although schema-mode inputs require `validators`, this + * returns a type normalized to `FormOptions`, where `validators` is optional. + * This tradeoff enables safer inference and reuse. * * @example * ```ts @@ -89,24 +123,32 @@ export type NullableSchemaData> = * @typeParam TFormValidators - Library-managed. Do not specify explicitly. * @typeParam TFormData - Library-managed. Do not specify explicitly. * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. + * @typeParam TComponents - Library-managed. Do not specify explicitly. */ -export type FormOptionsStrictSchemaFn = < +export type FormOptionsStrictSchemaFn = < const TFormValidators extends FormValidators, // Not quite sure why, but using FormValidatorData directly in the generic breaks things. // Probably something recursive going on that resolves it to `never`? TFormData extends FormValidatorData, TSubmitReturn, >( - options: FormOptions, + options: StandardSchemaFormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => FormOptions< FormValidatorData, TFormValidators, - TSubmitReturn + TSubmitReturn, + TComponents > /** * Infers the form data shape from a Standard Schema validator while allowing - * editable defaults to contain `null` or `undefined` values. + * editable defaults to omit properties or contain `null` or `undefined` + * values. * * Use this when the schema represents the final valid shape but the UI needs * intermediate empty states, such as an unselected date. Raw form state @@ -116,14 +158,13 @@ export type FormOptionsStrictSchemaFn = < * At runtime, this returns the original options object and does not run the * schema. * - * Include the schema in `validators` to provide the type inference and - * perform validation. + * `validators` must contain at least one Standard Schema to provide the type + * inference and perform validation. * * @remarks - * **Important:** Although this returns the original object unchanged at - * runtime, its type is normalized to `FormOptions`. Optional properties such - * as `validators` therefore remain optional even when supplied. This - * tradeoff enables safer inference and reuse. + * **Important:** Although schema-mode inputs require `validators`, this + * returns a type normalized to `FormOptions`, where `validators` is optional. + * This tradeoff enables safer inference and reuse. * * @example * ```ts @@ -140,23 +181,30 @@ export type FormOptionsStrictSchemaFn = < * ``` * * @returns The original options object, normalized to `FormOptions` with - * nullable and undefined editable states merged into the schema's input - * shape. + * omitted, nullable, and undefined editable states merged into the schema's + * input shape. * @typeParam TFormValidators - Library-managed. Do not specify explicitly. * @typeParam TFormData - Library-managed. Do not specify explicitly. * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. + * @typeParam TComponents - Library-managed. Do not specify explicitly. * */ -export type FormOptionsLooseSchemaFn = < +export type FormOptionsLooseSchemaFn = < const TFormValidators extends FormValidators, const TFormData extends NullableSchemaData, TSubmitReturn, >( - options: FormOptions, + options: StandardSchemaFormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => FormOptions< InferUnion>, TFormValidators, - TSubmitReturn + TSubmitReturn, + TComponents > /** @@ -165,8 +213,10 @@ export type FormOptionsLooseSchemaFn = < * * Use `formOptions` directly instead of naming this interface in application * code. + * + * @typeParam TComponents - Library-managed. Do not specify explicitly. */ -export interface FormOptionsApi { +export interface FormOptionsApi { /** * Keeps types inferred from `defaultValues`, validators, and submission * callbacks when form options are declared separately. @@ -192,8 +242,8 @@ export interface FormOptionsApi { const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, - ): FormOptions + options: FormOptions, + ): FormOptions /** * Infers the form data type from a Standard Schema validator and requires @@ -206,14 +256,13 @@ export interface FormOptionsApi { * At runtime, this returns the original options object and does not run the * schema. * - * Include the schema in `validators` to provide the type inference and - * perform validation. + * `validators` must contain at least one Standard Schema to provide the type + * inference and perform validation. * * @remarks - * **Important:** Although this returns the original object unchanged at - * runtime, its type is normalized to `FormOptions`. Optional properties such - * as `validators` therefore remain optional even when supplied. This - * tradeoff enables safer inference and reuse. + * **Important:** Although schema-mode inputs require `validators`, this + * returns a type normalized to `FormOptions`, where `validators` is optional. + * This tradeoff enables safer inference and reuse. * * @example * ```ts @@ -235,11 +284,12 @@ export interface FormOptionsApi { * @typeParam TFormData - Library-managed. Do not specify explicitly. * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. */ - strictSchema: FormOptionsStrictSchemaFn + strictSchema: FormOptionsStrictSchemaFn /** * Infers the form data shape from a Standard Schema validator while allowing - * editable defaults to contain `null` or `undefined` values. + * editable defaults to omit properties or contain `null` or `undefined` + * values. * * Use this when the schema represents the final valid shape but the UI needs * intermediate empty states, such as an unselected date. Raw form state @@ -249,14 +299,13 @@ export interface FormOptionsApi { * At runtime, this returns the original options object and does not run the * schema. * - * Include the schema in `validators` to provide the type inference and - * perform validation. + * `validators` must contain at least one Standard Schema to provide the type + * inference and perform validation. * * @remarks - * **Important:** Although this returns the original object unchanged at - * runtime, its type is normalized to `FormOptions`. Optional properties such - * as `validators` therefore remain optional even when supplied. This - * tradeoff enables safer inference and reuse. + * **Important:** Although schema-mode inputs require `validators`, this + * returns a type normalized to `FormOptions`, where `validators` is optional. + * This tradeoff enables safer inference and reuse. * * @example * ```ts @@ -273,13 +322,13 @@ export interface FormOptionsApi { * ``` * * @returns The original options object, normalized to `FormOptions` with - * nullable and undefined editable states merged into the schema's input - * shape. + * omitted, nullable, and undefined editable states merged into the schema's + * input shape. * @typeParam TFormValidators - Library-managed. Do not specify explicitly. * @typeParam TFormData - Library-managed. Do not specify explicitly. * @typeParam TSubmitReturn - Library-managed. Do not specify explicitly. */ - looseSchema: FormOptionsLooseSchemaFn + looseSchema: FormOptionsLooseSchemaFn } /** @@ -289,8 +338,8 @@ export interface FormOptionsApi { * The regular helper takes `defaultValues` at face value as the form data * shape. For schema-driven inference, use `formOptions.strictSchema` when the * schema defines an input-to-output boundary, or `formOptions.looseSchema` when - * the schema defines the shape but editable defaults need `null` or - * `undefined` values. + * the schema defines the shape but editable defaults may omit properties or + * need `null` or `undefined` values. * * At runtime, this is an identity helper: it returns the original options * object and does not create a form or run validation. @@ -322,7 +371,7 @@ export interface FormOptionsApi { */ const formOptions = ((opts) => { return opts -}) as FormOptionsApi +}) as FormOptionsApi formOptions.strictSchema = (opts) => opts formOptions.looseSchema = (opts) => opts as never diff --git a/packages/form-core/src/validation.public.ts b/packages/form-core/src/validation.public.ts index 457fb865ed..9145fc9373 100644 --- a/packages/form-core/src/validation.public.ts +++ b/packages/form-core/src/validation.public.ts @@ -94,6 +94,26 @@ type InferFormDataFromValidator = ? TGroupValue : any +/** + * The validator produced by applying a run function or Standard Schema to a + * reusable `createValidator` configuration. + * + * This type is inferred from `createValidator`; application code normally + * does not need to name it directly. + * + * @typeParam TOptions - Library-managed. Do not specify explicitly. + * @typeParam TRun - Library-managed. Do not specify explicitly. + */ +export type CreatedValidator< + TOptions extends ValidatorOptions, + TRun extends ValidatorRun, +> = ValidatorWithRun< + InferFormDataFromValidator, + InferFormDataFromValidator, + TOptions, + TRun +> + type ValidatorRunsFromOptions< in out TOptions extends readonly [ ValidatorOptions, @@ -126,12 +146,7 @@ export function createValidator< options: TOptions, ): ( run: TValidator, -) => ValidatorWithRun< - InferFormDataFromValidator, - InferFormDataFromValidator, - TOptions, - TValidator -> { +) => CreatedValidator { return (run: ValidatorRun) => ({ ...options, run }) as never } diff --git a/packages/form-core/tests/serverValidate.test-d.ts b/packages/form-core/tests/serverValidate.test-d.ts index 6e0ecfcd0a..a5147d5a1b 100644 --- a/packages/form-core/tests/serverValidate.test-d.ts +++ b/packages/form-core/tests/serverValidate.test-d.ts @@ -316,7 +316,12 @@ describe('server validation types', () => { const TFormValidators extends FormValidators, TSubmitReturn, >( - _options: FormOptions, + _options: FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => { return (values: TFormData) => Promise.resolve(values) }, @@ -346,7 +351,12 @@ describe('server validation types', () => { const TFormValidators extends FormValidators, TSubmitReturn, >( - _options: FormOptions, + _options: FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, _pluginOptions?: { field: keyof TFormData }, ) => { return Object.assign((values: TFormData) => Promise.resolve(values), { diff --git a/packages/form-core/tests/validation-public.test.ts b/packages/form-core/tests/validation-public.test.ts index 8e826f20df..34273b0e57 100644 --- a/packages/form-core/tests/validation-public.test.ts +++ b/packages/form-core/tests/validation-public.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'vitest' +import z from 'zod' import { createErrorMap, createErrorVisibility, @@ -10,10 +11,20 @@ import { describe('validation public helpers', () => { it('returns form options unchanged at runtime', () => { const options = { defaultValues: { name: 'Ada' } } + const triggers: Array<'change'> = ['change'] + const schemaOptions = { + ...options, + validators: [ + { + run: z.object({ name: z.string() }), + triggers, + }, + ], + } expect(formOptions(options)).toBe(options) - expect(formOptions.strictSchema(options)).toBe(options) - expect(formOptions.looseSchema(options)).toBe(options) + expect(formOptions.strictSchema(schemaOptions)).toBe(schemaOptions) + expect(formOptions.looseSchema(schemaOptions)).toBe(schemaOptions) }) it('creates validators by pairing options with run functions', () => { diff --git a/packages/form-core/tests/validation.test-d.ts b/packages/form-core/tests/validation.test-d.ts index 71b099acab..eeeaa828cc 100644 --- a/packages/form-core/tests/validation.test-d.ts +++ b/packages/form-core/tests/validation.test-d.ts @@ -2,11 +2,11 @@ import { describe, expectTypeOf, it } from 'vitest' import z from 'zod' import { InternalFormApi } from '../src/FormApi/FormApi.lib' import { - createErrorMap, createErrorVisibility, createValidator, createValidators, formOptions, + createErrorMap as importCreateErrorMap, } from '../src' import type { AnyFieldApi, @@ -81,12 +81,91 @@ type TestFieldErrors< > > +describe('formOptions', () => { + it('infers form data from defaultValues', () => { + const options = formOptions({ + defaultValues: { + name: '', + age: 0, + }, + validators: [], + }) + + expectTypeOf(options.defaultValues).toEqualTypeOf<{ + name: string + age: number + }>() + }) + + it('infers form data from a strict schema', () => { + const options = formOptions.strictSchema({ + defaultValues: { name: '' }, + validators: [ + { + run: z.object({ name: z.string() }), + triggers: ['change'], + }, + ], + }) + + expectTypeOf(options.defaultValues).toEqualTypeOf<{ name: string }>() + }) + + it('rejects strict schema options without a schema', () => { + // @ts-expect-error Schema modes require a Standard Schema validator. + const options = formOptions.strictSchema({ + defaultValues: { name: '' }, + }) + + void options + }) + + it('allows loose schema defaults to omit properties', () => { + const options = formOptions.looseSchema({ + defaultValues: { + address: { + city: null, + }, + }, + validators: [ + { + run: z.object({ + name: z.string(), + address: z.object({ + city: z.string(), + postcode: z.number(), + }), + }), + triggers: ['change'], + }, + ], + }) + + expectTypeOf(options.defaultValues).toEqualTypeOf<{ + name: string | undefined + address: { + city: string | null + postcode: number | undefined + } + }>() + }) + + it('rejects loose schema options without a schema', () => { + // @ts-expect-error Schema modes require a Standard Schema validator. + const options = formOptions.looseSchema({ + defaultValues: { name: '' }, + }) + + void options + }) +}) describe('ErrorVisibility', () => { it('types callback scoped and pre-visibility field state', () => { const options: FormOptions< TestFormData, typeof emptyFormValidators, - never + never, + unknown > = { defaultValues: { name: '' }, errorVisibility: ({ state, fieldState }) => { @@ -177,10 +256,11 @@ describe('ErrorVisibility', () => { }) it('rejects removed string presets', () => { - const formOptions: FormOptions< + const formOpts: FormOptions< TestFormData, typeof emptyFormValidators, - never + never, + unknown > = { defaultValues: { name: '' }, // @ts-expect-error String visibility presets were replaced by callbacks. @@ -200,7 +280,7 @@ describe('ErrorVisibility', () => { errorVisibility: 'always', } - void formOptions + void formOpts void fieldOptions }) }) @@ -214,18 +294,18 @@ describe('createErrorMap', () => { } } - const errors = createErrorMap() + const errors = importCreateErrorMap() const initial: ValidationErrorMap = { form: 'Initial form error', fields: { name: 'Initial name error' }, } expectTypeOf(errors).toEqualTypeOf>() - expectTypeOf(createErrorMap(initial)).toEqualTypeOf< + expectTypeOf(importCreateErrorMap(initial)).toEqualTypeOf< ValidationErrorMap >() expectTypeOf( - createErrorMap({ form: 'Partial form error' }), + importCreateErrorMap({ form: 'Partial form error' }), ).toEqualTypeOf>() errors.form = 'Form error' @@ -623,7 +703,6 @@ describe('FormErrors', () => { it('should normalize async errors', () => { const validators = defineFormValidators([ - // eslint-disable-next-line @typescript-eslint/require-await { run: async () => ['First error', 'Second error'], triggers: [] }, ]) @@ -1214,12 +1293,6 @@ describe('FieldErrors', () => { }) describe('validator type transforms', () => { - function defineFormValidators< - const TFormValidators extends FormValidators, - >(validators: TFormValidators): TFormValidators { - return validators - } - it('it should transform a schema', () => { const vs = defineFormValidators([ { diff --git a/packages/lit-form/src/get-form-type.ts b/packages/lit-form/src/get-form-type.ts index 9e3c061b14..471c74ee89 100644 --- a/packages/lit-form/src/get-form-type.ts +++ b/packages/lit-form/src/get-form-type.ts @@ -59,7 +59,8 @@ export type LitFormType = TOptions extends FormOptions< infer TFormData, infer TFormValidators, - infer TSubmitReturn + infer TSubmitReturn, + unknown > ? TanStackFormController< TFormData, diff --git a/packages/lit-form/src/tanstack-form-controller.ts b/packages/lit-form/src/tanstack-form-controller.ts index 15950f1c25..fd6910b8a3 100644 --- a/packages/lit-form/src/tanstack-form-controller.ts +++ b/packages/lit-form/src/tanstack-form-controller.ts @@ -240,7 +240,7 @@ export class TanStackFormController< */ constructor( host: ReactiveControllerHost, - options: FormOptions, + options: FormOptions, ) { this.#form = new InternalFormApi(options) new TanStackStoreSelector(host, () => this.#form._atoms.resetVersion) @@ -262,7 +262,9 @@ export class TanStackFormController< } /** Updates reactive form options without replacing the form instance. */ - update(options: FormOptions) { + update( + options: FormOptions, + ) { this.#form._update(options) } diff --git a/packages/preact-form/src/AppForm/appFormOptions.public.ts b/packages/preact-form/src/AppForm/appFormOptions.public.ts deleted file mode 100644 index 8e8468cd3b..0000000000 --- a/packages/preact-form/src/AppForm/appFormOptions.public.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { - FormOptions, - FormValidatorData, - FormValidators, - InferUnion, - NullableSchemaData, -} from '@tanstack/form-core' -import type { AnyPreactFormComponentMap } from './componentMap.public' - -declare const componentsSymbol: unique symbol - -export interface AppFormOptions< - in out TFormData, - in out TFormValidators extends FormValidators, - in out TSubmitReturn, - out TComponents extends AnyPreactFormComponentMap, -> extends FormOptions { - [componentsSymbol]: TComponents -} - -export interface AppFormOptionsApi< - in out TComponents extends AnyPreactFormComponentMap, -> { - < - TFormData, - const TFormValidators extends FormValidators, - TSubmitReturn, - >( - options: FormOptions, - ): AppFormOptions - - strictSchema: < - const TFormValidators extends FormValidators, - // Not quite sure why, but using FormValidatorData directly in the generic breaks things. - // Probably something recursive going on that resolves it to `never`? - TFormData extends FormValidatorData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - FormValidatorData, - TFormValidators, - TSubmitReturn, - TComponents - > - - looseSchema: < - const TFormValidators extends FormValidators, - const TFormData extends NullableSchemaData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - InferUnion>, - TFormValidators, - TSubmitReturn, - TComponents - > -} diff --git a/packages/preact-form/src/AppForm/createFormHook.public.ts b/packages/preact-form/src/AppForm/createFormHook.public.ts index b81e889cae..7c984fd78a 100644 --- a/packages/preact-form/src/AppForm/createFormHook.public.ts +++ b/packages/preact-form/src/AppForm/createFormHook.public.ts @@ -2,18 +2,17 @@ import { useInternalForm } from '../PreactForm/PreactFormApi.lib' import { defineFieldGroup } from '../FieldGroup/withFields.public' import { createAppFormInitializer } from './initializeAppForm.lib' import { useFormContext } from './contexts.lib' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AppFormHookResult, CreateFormHookOptions, UseAppFormHook, } from './createFormHookTypes.public' import type { FunctionComponent } from 'preact/compat' -import type { FormOptions } from '@tanstack/form-core' +import type { FormOptions, FormOptionsApi } from '@tanstack/form-core' const appFormOptions = ((opts) => { return opts -}) as AppFormOptionsApi +}) as FormOptionsApi appFormOptions.strictSchema = (opts) => opts as never appFormOptions.looseSchema = (opts) => opts as never @@ -29,7 +28,7 @@ export function createFormHook< }> { const initializeAppForm = createAppFormInitializer(createOptions) - function useExtendedForm(hookOptions: FormOptions) { + function useExtendedForm(hookOptions: FormOptions) { const form = useInternalForm(hookOptions, initializeAppForm) return form } diff --git a/packages/preact-form/src/AppForm/createFormHookTypes.public.ts b/packages/preact-form/src/AppForm/createFormHookTypes.public.ts index 07905ef12f..fcbc87e8d6 100644 --- a/packages/preact-form/src/AppForm/createFormHookTypes.public.ts +++ b/packages/preact-form/src/AppForm/createFormHookTypes.public.ts @@ -1,4 +1,3 @@ -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AnyPreactFormComponentMap, PreactFormComponentMap, @@ -11,6 +10,7 @@ import type { DefaultFormGroupOptions, DefaultFormOptions, FormOptions, + FormOptionsApi, FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' @@ -102,7 +102,7 @@ export type UseAppFormHook< TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => PreactAppFormApi< TFormData, ToFormErrorTypes, @@ -142,7 +142,7 @@ export interface AppFormHookResult< * } * ``` */ - appFormOptions: AppFormOptionsApi + appFormOptions: FormOptionsApi /** * Defines a reusable field group whose fields expose the field components * registered with `createFormHook`. diff --git a/packages/preact-form/src/AppForm/initializeAppForm.lib.ts b/packages/preact-form/src/AppForm/initializeAppForm.lib.ts index 108abf0999..82a3842e29 100644 --- a/packages/preact-form/src/AppForm/initializeAppForm.lib.ts +++ b/packages/preact-form/src/AppForm/initializeAppForm.lib.ts @@ -20,7 +20,7 @@ interface AnyCreateFormHookOptions { export function createAppFormInitializer( createOptions: AnyCreateFormHookOptions, -): (options: FormOptions) => InternalPreactFormApi { +): (options: FormOptions) => InternalPreactFormApi { const hasDefaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || diff --git a/packages/preact-form/src/PreactForm/PreactFormApi.lib.tsx b/packages/preact-form/src/PreactForm/PreactFormApi.lib.tsx index 47e883512b..a869321d5d 100644 --- a/packages/preact-form/src/PreactForm/PreactFormApi.lib.tsx +++ b/packages/preact-form/src/PreactForm/PreactFormApi.lib.tsx @@ -14,7 +14,7 @@ export interface InternalPreactFormApi extends AnyInternalFormApi, PreactTanStackFormComponents {} export function initializeForm( - options: FormOptions, + options: FormOptions, ): InternalPreactFormApi { const form = new InternalFormApi(options) @@ -24,8 +24,10 @@ export function initializeForm( } export function useInternalForm( - options: FormOptions, - initializeFn: (options: FormOptions) => InternalPreactFormApi, + options: FormOptions, + initializeFn: ( + options: FormOptions, + ) => InternalPreactFormApi, ) { const preactFormId = usePreactId() const resolvedOptions = diff --git a/packages/preact-form/src/PreactForm/formType.public.ts b/packages/preact-form/src/PreactForm/formType.public.ts index d724ee71ca..76f67c04d5 100644 --- a/packages/preact-form/src/PreactForm/formType.public.ts +++ b/packages/preact-form/src/PreactForm/formType.public.ts @@ -4,7 +4,6 @@ import type { FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' -import type { AppFormOptions } from '../AppForm/appFormOptions.public' import type { AnyPreactFormComponentMap, DefaultPreactFormComponentMap, @@ -53,11 +52,8 @@ type PreactFormTypeErrorTypes< * * @typeParam TOptions - The reusable form or app-form options from which the API derives its form data, error, and registered-component types. */ -export type PreactFormType< - TOptions extends - AnyFormOptions | AppFormOptions, -> = - TOptions extends AppFormOptions< +export type PreactFormType = + TOptions extends FormOptions< infer TFormData, infer TFormValidators, infer TSubmitReturn, @@ -66,16 +62,8 @@ export type PreactFormType< ? PreactFormApi< TFormData, PreactFormTypeErrorTypes, - TComponents + TComponents extends AnyPreactFormComponentMap + ? TComponents + : DefaultPreactFormComponentMap > - : TOptions extends FormOptions< - infer TFormData, - infer TFormValidators, - infer TSubmitReturn - > - ? PreactFormApi< - TFormData, - PreactFormTypeErrorTypes, - DefaultPreactFormComponentMap - > - : never + : never diff --git a/packages/preact-form/src/PreactForm/useForm.public.ts b/packages/preact-form/src/PreactForm/useForm.public.ts index 0c4d7d54b3..cab79a8058 100644 --- a/packages/preact-form/src/PreactForm/useForm.public.ts +++ b/packages/preact-form/src/PreactForm/useForm.public.ts @@ -16,14 +16,14 @@ export type UseFormHook = const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => PreactFormApi< TFormData, ToFormErrorTypes, TComponents > -function useFormHook(options: FormOptions) { +function useFormHook(options: FormOptions) { const form = useInternalForm(options, initializeForm) return form } diff --git a/packages/preact-form/src/index.ts b/packages/preact-form/src/index.ts index a59ee434e5..66f29e591d 100644 --- a/packages/preact-form/src/index.ts +++ b/packages/preact-form/src/index.ts @@ -11,7 +11,6 @@ export * from './preactTypes.public' export * from './types.public' export * from './Subscribe.public' export * from './AppForm/PreactAppFormApi.public' -export * from './AppForm/appFormOptions.public' export * from './AppForm/componentMap.public' export * from './AppForm/createFormHook.public' export * from './AppForm/createFormHookTypes.public' diff --git a/packages/react-form-nextjs/src/index.ts b/packages/react-form-nextjs/src/index.ts index 1f3328a420..1ca5bf0958 100644 --- a/packages/react-form-nextjs/src/index.ts +++ b/packages/react-form-nextjs/src/index.ts @@ -24,7 +24,7 @@ type NextCreateServerValidate = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => NextServerValidate function decodeFormData( @@ -44,7 +44,12 @@ export function next( const TFormValidators extends FormValidators, TSubmitReturn, >( - formOptions: FormOptions, + formOptions: FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => { return async (formData) => { const values = decodeFormData(formData, options.info) diff --git a/packages/react-form-start/src/index.ts b/packages/react-form-start/src/index.ts index 99cbba8da9..7c448bf0e5 100644 --- a/packages/react-form-start/src/index.ts +++ b/packages/react-form-start/src/index.ts @@ -80,7 +80,7 @@ export type StartCreateServerValidate< const TFormValidators extends FormValidators, TSubmitReturn, >( - formOptions: FormOptions, + formOptions: FormOptions, options?: StartCreateServerValidateOptions, ) => StartServerValidateAction< TFormData, @@ -161,7 +161,12 @@ export function start( const TFormValidators extends FormValidators, TSubmitReturn, >( - formOptions: FormOptions, + formOptions: FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, formValidateOptions?: StartCreateServerValidateOptions, ): StartServerValidateAction< TFormData, diff --git a/packages/react-form/src/AppForm/appFormOptions.public.ts b/packages/react-form/src/AppForm/appFormOptions.public.ts deleted file mode 100644 index 2cb21aa706..0000000000 --- a/packages/react-form/src/AppForm/appFormOptions.public.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { - FormOptions, - FormValidatorData, - FormValidators, - InferUnion, - NullableSchemaData, -} from '@tanstack/form-core' -import type { AnyReactFormComponentMap } from './componentMap.public' - -declare const componentsSymbol: unique symbol - -export interface AppFormOptions< - in out TFormData, - in out TFormValidators extends FormValidators, - in out TSubmitReturn, - out TComponents extends AnyReactFormComponentMap, -> extends FormOptions { - [componentsSymbol]: TComponents -} - -export interface AppFormOptionsApi< - in out TComponents extends AnyReactFormComponentMap, -> { - < - TFormData, - const TFormValidators extends FormValidators, - TSubmitReturn, - >( - options: FormOptions, - ): AppFormOptions - - strictSchema: < - const TFormValidators extends FormValidators, - // Not quite sure why, but using FormValidatorData directly in the generic breaks things. - // Probably something recursive going on that resolves it to `never`? - TFormData extends FormValidatorData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - FormValidatorData, - TFormValidators, - TSubmitReturn, - TComponents - > - - looseSchema: < - const TFormValidators extends FormValidators, - const TFormData extends NullableSchemaData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - InferUnion>, - TFormValidators, - TSubmitReturn, - TComponents - > -} diff --git a/packages/react-form/src/AppForm/createFormHook.public.ts b/packages/react-form/src/AppForm/createFormHook.public.ts index e22014d632..1ffd2c15db 100644 --- a/packages/react-form/src/AppForm/createFormHook.public.ts +++ b/packages/react-form/src/AppForm/createFormHook.public.ts @@ -2,18 +2,17 @@ import { useInternalForm } from '../ReactForm/ReactFormApi.lib' import { defineFieldGroup } from '../FieldGroup/withFields.public' import { createAppFormInitializer } from './initializeAppForm.lib' import { useFormContext } from './contexts.lib' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AppFormHookResult, CreateFormHookOptions, UseAppFormHook, } from './createFormHookTypes.public' import type { FunctionComponent } from 'react' -import type { FormOptions } from '@tanstack/form-core' +import type { FormOptions, FormOptionsApi } from '@tanstack/form-core' const appFormOptions = ((opts) => { return opts -}) as AppFormOptionsApi +}) as FormOptionsApi appFormOptions.strictSchema = (opts) => opts as never appFormOptions.looseSchema = (opts) => opts as never @@ -29,7 +28,7 @@ export function createFormHook< }> { const initializeAppForm = createAppFormInitializer(createOptions) - function useExtendedForm(hookOptions: FormOptions) { + function useExtendedForm(hookOptions: FormOptions) { const form = useInternalForm(hookOptions, initializeAppForm) return form } diff --git a/packages/react-form/src/AppForm/createFormHookTypes.public.ts b/packages/react-form/src/AppForm/createFormHookTypes.public.ts index 583606d599..2bf7145f5d 100644 --- a/packages/react-form/src/AppForm/createFormHookTypes.public.ts +++ b/packages/react-form/src/AppForm/createFormHookTypes.public.ts @@ -1,4 +1,3 @@ -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AnyReactFormComponentMap, ReactFormComponentMap, @@ -11,6 +10,7 @@ import type { DefaultFormGroupOptions, DefaultFormOptions, FormOptions, + FormOptionsApi, FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' @@ -102,7 +102,7 @@ export type UseAppFormHook< TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => ReactAppFormApi< TFormData, ToFormErrorTypes, @@ -142,7 +142,7 @@ export interface AppFormHookResult< * } * ``` */ - appFormOptions: AppFormOptionsApi + appFormOptions: FormOptionsApi /** * Defines a field group whose fields expose the field components registered * with `createFormHook`. diff --git a/packages/react-form/src/AppForm/initializeAppForm.lib.ts b/packages/react-form/src/AppForm/initializeAppForm.lib.ts index a84ccd47f3..b8bbdca8a3 100644 --- a/packages/react-form/src/AppForm/initializeAppForm.lib.ts +++ b/packages/react-form/src/AppForm/initializeAppForm.lib.ts @@ -20,7 +20,7 @@ interface AnyCreateFormHookOptions { export function createAppFormInitializer( createOptions: AnyCreateFormHookOptions, -): (options: FormOptions) => InternalReactFormApi { +): (options: FormOptions) => InternalReactFormApi { const hasDefaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || diff --git a/packages/react-form/src/ReactForm/ReactFormApi.lib.tsx b/packages/react-form/src/ReactForm/ReactFormApi.lib.tsx index f79d1e2b3c..1236ed81f7 100644 --- a/packages/react-form/src/ReactForm/ReactFormApi.lib.tsx +++ b/packages/react-form/src/ReactForm/ReactFormApi.lib.tsx @@ -13,7 +13,7 @@ export interface InternalReactFormApi extends AnyInternalFormApi, ReactTanStackFormComponents {} export function initializeForm( - options: FormOptions, + options: FormOptions, ): InternalReactFormApi { const form = new InternalFormApi(options) @@ -23,8 +23,10 @@ export function initializeForm( } export function useInternalForm( - options: FormOptions, - initializeFn: (options: FormOptions) => InternalReactFormApi, + options: FormOptions, + initializeFn: ( + options: FormOptions, + ) => InternalReactFormApi, ) { const reactFormId = useReactId() const resolvedOptions = diff --git a/packages/react-form/src/ReactForm/formType.public.ts b/packages/react-form/src/ReactForm/formType.public.ts index 5c903ae349..a02f7c4d0a 100644 --- a/packages/react-form/src/ReactForm/formType.public.ts +++ b/packages/react-form/src/ReactForm/formType.public.ts @@ -4,7 +4,6 @@ import type { FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' -import type { AppFormOptions } from '../AppForm/appFormOptions.public' import type { AnyReactFormComponentMap, DefaultReactFormComponentMap, @@ -53,11 +52,8 @@ type ReactFormTypeErrorTypes< * * @typeParam TOptions - The reusable form or app-form options from which the API derives its form data, error, and registered-component types. */ -export type ReactFormType< - TOptions extends - AnyFormOptions | AppFormOptions, -> = - TOptions extends AppFormOptions< +export type ReactFormType = + TOptions extends FormOptions< infer TFormData, infer TFormValidators, infer TSubmitReturn, @@ -66,16 +62,8 @@ export type ReactFormType< ? ReactFormApi< TFormData, ReactFormTypeErrorTypes, - TComponents + TComponents extends AnyReactFormComponentMap + ? TComponents + : DefaultReactFormComponentMap > - : TOptions extends FormOptions< - infer TFormData, - infer TFormValidators, - infer TSubmitReturn - > - ? ReactFormApi< - TFormData, - ReactFormTypeErrorTypes, - DefaultReactFormComponentMap - > - : never + : never diff --git a/packages/react-form/src/ReactForm/useForm.public.ts b/packages/react-form/src/ReactForm/useForm.public.ts index d1efbd2f8d..bd0adefd85 100644 --- a/packages/react-form/src/ReactForm/useForm.public.ts +++ b/packages/react-form/src/ReactForm/useForm.public.ts @@ -15,14 +15,14 @@ export type UseFormHook = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => ReactFormApi< TFormData, ToFormErrorTypes, TComponents > -function useFormHook(options: FormOptions) { +function useFormHook(options: FormOptions) { const form = useInternalForm(options, initializeForm) return form } diff --git a/packages/react-form/src/index.ts b/packages/react-form/src/index.ts index e5cf30f969..ddc8fe0fde 100644 --- a/packages/react-form/src/index.ts +++ b/packages/react-form/src/index.ts @@ -10,7 +10,6 @@ export * from './FieldGroup/withFields.public' export * from './types.public' export * from './Subscribe.public' export * from './AppForm/ReactAppFormApi.public' -export * from './AppForm/appFormOptions.public' export * from './AppForm/componentMap.public' export * from './AppForm/createFormHook.public' export * from './AppForm/createFormHookTypes.public' diff --git a/packages/solid-form/src/AppForm/appFormOptions.public.ts b/packages/solid-form/src/AppForm/appFormOptions.public.ts deleted file mode 100644 index 43b9a22920..0000000000 --- a/packages/solid-form/src/AppForm/appFormOptions.public.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { - FormOptions, - FormValidatorData, - FormValidators, - InferUnion, - NullableSchemaData, -} from '@tanstack/form-core' -import type { AnySolidFormComponentMap } from './componentMap.public' - -declare const componentsSymbol: unique symbol - -export interface AppFormOptions< - TFormData, - TFormValidators extends FormValidators, - TSubmitReturn, - TComponents extends AnySolidFormComponentMap, -> extends FormOptions { - [componentsSymbol]: TComponents -} - -export interface AppFormOptionsApi< - TComponents extends AnySolidFormComponentMap, -> { - < - TFormData, - const TFormValidators extends FormValidators, - TSubmitReturn, - >( - options: FormOptions, - ): AppFormOptions - - strictSchema: < - const TFormValidators extends FormValidators, - TFormData extends FormValidatorData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - FormValidatorData, - TFormValidators, - TSubmitReturn, - TComponents - > - - looseSchema: < - const TFormValidators extends FormValidators, - const TFormData extends NullableSchemaData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - InferUnion>, - TFormValidators, - TSubmitReturn, - TComponents - > -} diff --git a/packages/solid-form/src/AppForm/createFormHook.public.ts b/packages/solid-form/src/AppForm/createFormHook.public.ts index 7a1ef6ab12..c14034ca03 100644 --- a/packages/solid-form/src/AppForm/createFormHook.public.ts +++ b/packages/solid-form/src/AppForm/createFormHook.public.ts @@ -2,16 +2,15 @@ import { createInternalForm } from '../SolidFormApi.lib' import { defineFieldGroup } from '../FieldGroup/withFields.public' import { createAppFormInitializer } from './initializeAppForm.lib' import { useFormContext } from './contexts.lib' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AppFormHookResult, CreateFormHookOptions, UseAppFormHook, } from './createFormHookTypes.public' import type { Accessor, Component } from 'solid-js' -import type { FormOptions } from '@tanstack/form-core' +import type { FormOptions, FormOptionsApi } from '@tanstack/form-core' -const appFormOptions = ((opts: unknown) => opts) as AppFormOptionsApi +const appFormOptions = ((opts: unknown) => opts) as FormOptionsApi appFormOptions.strictSchema = (opts) => opts as never appFormOptions.looseSchema = (opts) => opts as never @@ -26,7 +25,9 @@ export function createFormHook< }> { const initializeAppForm = createAppFormInitializer(createOptions) - function useExtendedForm(options: Accessor>) { + function useExtendedForm( + options: Accessor>, + ) { return createInternalForm(options, initializeAppForm) } const useAppForm = useExtendedForm as never as UseAppFormHook<{ diff --git a/packages/solid-form/src/AppForm/createFormHookTypes.public.ts b/packages/solid-form/src/AppForm/createFormHookTypes.public.ts index 19836a7f06..4440f6da2d 100644 --- a/packages/solid-form/src/AppForm/createFormHookTypes.public.ts +++ b/packages/solid-form/src/AppForm/createFormHookTypes.public.ts @@ -1,5 +1,4 @@ import type { Accessor, Component } from 'solid-js' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AnySolidFormComponentMap, SolidFormComponentMap, @@ -11,6 +10,7 @@ import type { DefaultFormGroupOptions, DefaultFormOptions, FormOptions, + FormOptionsApi, FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' @@ -100,7 +100,9 @@ export type UseAppFormHook = < TFormValidators extends FormValidators, TSubmitReturn, >( - options: Accessor>, + options: Accessor< + FormOptions + >, ) => SolidAppFormApi< TFormData, ToFormErrorTypes, @@ -110,7 +112,7 @@ export type UseAppFormHook = < export interface AppFormHookResult< TComponents extends AnySolidFormComponentMap, > { - appFormOptions: AppFormOptionsApi + appFormOptions: FormOptionsApi defineAppFieldGroup: DefineFieldGroupFn useAppForm: UseAppFormHook useFormContext: () => SolidAppFormApi diff --git a/packages/solid-form/src/AppForm/initializeAppForm.lib.ts b/packages/solid-form/src/AppForm/initializeAppForm.lib.ts index 8c2a9966ce..ddd8f49d09 100644 --- a/packages/solid-form/src/AppForm/initializeAppForm.lib.ts +++ b/packages/solid-form/src/AppForm/initializeAppForm.lib.ts @@ -20,7 +20,7 @@ interface AnyCreateFormHookOptions { export function createAppFormInitializer( createOptions: AnyCreateFormHookOptions, -): (options: FormOptions) => InternalSolidFormApi { +): (options: FormOptions) => InternalSolidFormApi { const hasDefaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || diff --git a/packages/solid-form/src/SolidFormApi.lib.ts b/packages/solid-form/src/SolidFormApi.lib.ts index 69e66d1c85..4c0ae80726 100644 --- a/packages/solid-form/src/SolidFormApi.lib.ts +++ b/packages/solid-form/src/SolidFormApi.lib.ts @@ -144,14 +144,16 @@ function attachSolidFormGroupComponents( } export function initializeForm( - options: FormOptions, + options: FormOptions, ): InternalSolidFormApi { return attachSolidFormComponents(new InternalFormApi(options), null) } export function createInternalForm( - options: () => FormOptions, - initializeFn: (options: FormOptions) => InternalSolidFormApi, + options: () => FormOptions, + initializeFn: ( + options: FormOptions, + ) => InternalSolidFormApi, ) { const solidFormId = createUniqueId() const resolveOptions = () => { diff --git a/packages/solid-form/src/createForm.public.ts b/packages/solid-form/src/createForm.public.ts index e785c4f6d0..22e49a2a9d 100644 --- a/packages/solid-form/src/createForm.public.ts +++ b/packages/solid-form/src/createForm.public.ts @@ -13,14 +13,18 @@ export type CreateFormHook = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: Accessor>, + options: Accessor< + FormOptions + >, ) => SolidFormApi< TFormData, ToFormErrorTypes, DefaultSolidFormComponentMap > -function createFormHook(options: Accessor>) { +function createFormHook( + options: Accessor>, +) { return createInternalForm(options, initializeForm) } diff --git a/packages/solid-form/src/formType.public.ts b/packages/solid-form/src/formType.public.ts index b26a0cf07d..aed344edc0 100644 --- a/packages/solid-form/src/formType.public.ts +++ b/packages/solid-form/src/formType.public.ts @@ -4,7 +4,6 @@ import type { FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' -import type { AppFormOptions } from './AppForm/appFormOptions.public' import type { AnySolidFormComponentMap, DefaultSolidFormComponentMap, @@ -47,11 +46,8 @@ type SolidFormTypeErrorTypes< * * @typeParam TOptions - The reusable form or app-form options from which the API derives its form data, error, and registered-component types. */ -export type SolidFormType< - TOptions extends - AnyFormOptions | AppFormOptions, -> = - TOptions extends AppFormOptions< +export type SolidFormType = + TOptions extends FormOptions< infer TFormData, infer TFormValidators, infer TSubmitReturn, @@ -60,16 +56,8 @@ export type SolidFormType< ? SolidFormApi< TFormData, SolidFormTypeErrorTypes, - TComponents + TComponents extends AnySolidFormComponentMap + ? TComponents + : DefaultSolidFormComponentMap > - : TOptions extends FormOptions< - infer TFormData, - infer TFormValidators, - infer TSubmitReturn - > - ? SolidFormApi< - TFormData, - SolidFormTypeErrorTypes, - DefaultSolidFormComponentMap - > - : never + : never diff --git a/packages/solid-form/src/index.ts b/packages/solid-form/src/index.ts index 4e666bad23..9ff6e01851 100644 --- a/packages/solid-form/src/index.ts +++ b/packages/solid-form/src/index.ts @@ -9,7 +9,6 @@ export * from './Subscribe.public' export * from './FieldGroup/FieldGroupApi.public' export * from './FieldGroup/withFields.public' export * from './AppForm/SolidAppFormApi.public' -export * from './AppForm/appFormOptions.public' export * from './AppForm/componentMap.public' export * from './AppForm/createFormHook.public' export * from './AppForm/createFormHookTypes.public' diff --git a/packages/svelte-form/src/AppForm/appFormOptions.public.ts b/packages/svelte-form/src/AppForm/appFormOptions.public.ts deleted file mode 100644 index b5f69a5f17..0000000000 --- a/packages/svelte-form/src/AppForm/appFormOptions.public.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { - FormOptions, - FormValidatorData, - FormValidators, - InferUnion, - NullableSchemaData, -} from '@tanstack/form-core' -import type { AnySvelteFormComponentMap } from './componentMap.public' - -declare const componentsSymbol: unique symbol - -export interface AppFormOptions< - TFormData, - TFormValidators extends FormValidators, - TSubmitReturn, - TComponents extends AnySvelteFormComponentMap, -> extends FormOptions { - [componentsSymbol]: TComponents -} - -export interface AppFormOptionsApi< - TComponents extends AnySvelteFormComponentMap, -> { - < - TFormData, - const TFormValidators extends FormValidators, - TSubmitReturn, - >( - options: FormOptions, - ): AppFormOptions - - strictSchema: < - const TFormValidators extends FormValidators, - TFormData extends FormValidatorData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - FormValidatorData, - TFormValidators, - TSubmitReturn, - TComponents - > - - looseSchema: < - const TFormValidators extends FormValidators, - const TFormData extends NullableSchemaData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - InferUnion>, - TFormValidators, - TSubmitReturn, - TComponents - > -} diff --git a/packages/svelte-form/src/AppForm/createFormHook.public.ts b/packages/svelte-form/src/AppForm/createFormHook.public.ts index 96fecbc8d1..248a3907bf 100644 --- a/packages/svelte-form/src/AppForm/createFormHook.public.ts +++ b/packages/svelte-form/src/AppForm/createFormHook.public.ts @@ -2,16 +2,15 @@ import { createInternalForm } from '../createForm.svelte' import { defineFieldGroup } from '../FieldGroup/withFields.public' import { createAppFormInitializer } from './initializeAppForm.lib' import { useFormContext } from './contexts.lib' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AppFormHookResult, CreateFormHookOptions, UseAppFormHook, } from './createFormHookTypes.public' import type { Component } from 'svelte' -import type { FormOptions } from '@tanstack/form-core' +import type { FormOptions, FormOptionsApi } from '@tanstack/form-core' -const appFormOptions = ((opts: unknown) => opts) as AppFormOptionsApi +const appFormOptions = ((opts: unknown) => opts) as FormOptionsApi appFormOptions.strictSchema = (opts) => opts as never appFormOptions.looseSchema = (opts) => opts as never @@ -26,7 +25,7 @@ export function createFormHook< }> { const initializeAppForm = createAppFormInitializer(createOptions) - function useExtendedForm(options: () => FormOptions) { + function useExtendedForm(options: () => FormOptions) { return createInternalForm(options, initializeAppForm) } const useAppForm = useExtendedForm as never as UseAppFormHook<{ diff --git a/packages/svelte-form/src/AppForm/createFormHookTypes.public.ts b/packages/svelte-form/src/AppForm/createFormHookTypes.public.ts index 87a0289d07..33f74289d1 100644 --- a/packages/svelte-form/src/AppForm/createFormHookTypes.public.ts +++ b/packages/svelte-form/src/AppForm/createFormHookTypes.public.ts @@ -1,4 +1,3 @@ -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AnySvelteFormComponentMap, SvelteFormComponentMap, @@ -11,6 +10,7 @@ import type { DefaultFormGroupOptions, DefaultFormOptions, FormOptions, + FormOptionsApi, FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' @@ -100,7 +100,12 @@ export type UseAppFormHook = < TFormValidators extends FormValidators, TSubmitReturn, >( - options: () => FormOptions, + options: () => FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => SvelteAppFormApi< TFormData, ToFormErrorTypes, @@ -110,7 +115,7 @@ export type UseAppFormHook = < export interface AppFormHookResult< TComponents extends AnySvelteFormComponentMap, > { - appFormOptions: AppFormOptionsApi + appFormOptions: FormOptionsApi defineAppFieldGroup: DefineFieldGroupFn useAppForm: UseAppFormHook useFormContext: () => SvelteAppFormApi diff --git a/packages/svelte-form/src/AppForm/initializeAppForm.lib.ts b/packages/svelte-form/src/AppForm/initializeAppForm.lib.ts index 239daca588..0aab16c113 100644 --- a/packages/svelte-form/src/AppForm/initializeAppForm.lib.ts +++ b/packages/svelte-form/src/AppForm/initializeAppForm.lib.ts @@ -20,7 +20,7 @@ interface AnyCreateFormHookOptions { export function createAppFormInitializer( createOptions: AnyCreateFormHookOptions, -): (options: FormOptions) => InternalSvelteFormApi { +): (options: FormOptions) => InternalSvelteFormApi { const hasDefaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || diff --git a/packages/svelte-form/src/createForm.public.ts b/packages/svelte-form/src/createForm.public.ts index b6e74a5118..84a587d6fa 100644 --- a/packages/svelte-form/src/createForm.public.ts +++ b/packages/svelte-form/src/createForm.public.ts @@ -12,14 +12,19 @@ export type CreateForm = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: () => FormOptions, + options: () => FormOptions< + TFormData, + TFormValidators, + TSubmitReturn, + unknown + >, ) => SvelteFormApi< TFormData, ToFormErrorTypes, DefaultSvelteFormComponentMap > -function createFormImpl(options: () => FormOptions) { +function createFormImpl(options: () => FormOptions) { return createInternalForm(options, initializeForm) } diff --git a/packages/svelte-form/src/createForm.svelte.ts b/packages/svelte-form/src/createForm.svelte.ts index 07233ffd16..841078c427 100644 --- a/packages/svelte-form/src/createForm.svelte.ts +++ b/packages/svelte-form/src/createForm.svelte.ts @@ -56,14 +56,16 @@ export function attachSvelteFormComponents( } export function initializeForm( - options: FormOptions, + options: FormOptions, ): InternalSvelteFormApi { return attachSvelteFormComponents(new InternalFormApi(options), null) } export function createInternalForm( - options: () => FormOptions, - initialize: (options: FormOptions) => InternalSvelteFormApi, + options: () => FormOptions, + initialize: ( + options: FormOptions, + ) => InternalSvelteFormApi, ): InternalSvelteFormApi { const form = initialize(options()) diff --git a/packages/svelte-form/src/formType.public.ts b/packages/svelte-form/src/formType.public.ts index 9d4a9dbbfe..44333b65ef 100644 --- a/packages/svelte-form/src/formType.public.ts +++ b/packages/svelte-form/src/formType.public.ts @@ -4,7 +4,6 @@ import type { FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' -import type { AppFormOptions } from './AppForm/appFormOptions.public' import type { AnySvelteFormComponentMap, DefaultSvelteFormComponentMap, @@ -18,11 +17,8 @@ type SvelteFormTypeErrorTypes< ? any : ToFormErrorTypes -export type SvelteFormType< - TOptions extends - AnyFormOptions | AppFormOptions, -> = - TOptions extends AppFormOptions< +export type SvelteFormType = + TOptions extends FormOptions< infer TData, infer TValidators, infer TSubmitReturn, @@ -31,16 +27,8 @@ export type SvelteFormType< ? SvelteFormApi< TData, SvelteFormTypeErrorTypes, - TComponents + TComponents extends AnySvelteFormComponentMap + ? TComponents + : DefaultSvelteFormComponentMap > - : TOptions extends FormOptions< - infer TData, - infer TValidators, - infer TSubmitReturn - > - ? SvelteFormApi< - TData, - SvelteFormTypeErrorTypes, - DefaultSvelteFormComponentMap - > - : never + : never diff --git a/packages/svelte-form/src/index.ts b/packages/svelte-form/src/index.ts index 92a2042e1f..a6a4ab8491 100644 --- a/packages/svelte-form/src/index.ts +++ b/packages/svelte-form/src/index.ts @@ -12,7 +12,6 @@ export { default as FormGroup } from './FormGroup.svelte' export * from './FieldGroup/FieldGroupApi.public' export * from './FieldGroup/withFields.public' export * from './AppForm/SvelteAppFormApi.public' -export * from './AppForm/appFormOptions.public' export * from './AppForm/componentMap.public' export * from './AppForm/createFormHook.public' export * from './AppForm/createFormHookTypes.public' diff --git a/packages/vue-form/src/AppForm/appFormOptions.public.ts b/packages/vue-form/src/AppForm/appFormOptions.public.ts deleted file mode 100644 index 92f937a482..0000000000 --- a/packages/vue-form/src/AppForm/appFormOptions.public.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { - FormOptions, - FormValidatorData, - FormValidators, - InferUnion, - NullableSchemaData, -} from '@tanstack/form-core' -import type { AnyVueFormComponentMap } from './componentMap.public' - -declare const componentsSymbol: unique symbol - -export interface AppFormOptions< - TFormData, - TFormValidators extends FormValidators, - TSubmitReturn, - TComponents extends AnyVueFormComponentMap, -> extends FormOptions { - [componentsSymbol]: TComponents -} - -export interface AppFormOptionsApi { - < - TFormData, - const TFormValidators extends FormValidators, - TSubmitReturn, - >( - options: FormOptions, - ): AppFormOptions - - strictSchema: < - const TFormValidators extends FormValidators, - TFormData extends FormValidatorData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - FormValidatorData, - TFormValidators, - TSubmitReturn, - TComponents - > - - looseSchema: < - const TFormValidators extends FormValidators, - const TFormData extends NullableSchemaData, - TSubmitReturn, - >( - options: FormOptions, - ) => AppFormOptions< - InferUnion>, - TFormValidators, - TSubmitReturn, - TComponents - > -} diff --git a/packages/vue-form/src/AppForm/createFormHook.public.ts b/packages/vue-form/src/AppForm/createFormHook.public.ts index 878c41256e..7b5b8d760f 100644 --- a/packages/vue-form/src/AppForm/createFormHook.public.ts +++ b/packages/vue-form/src/AppForm/createFormHook.public.ts @@ -2,16 +2,15 @@ import { useInternalForm } from '../VueForm/VueFormApi.lib' import { defineFieldGroup } from '../FieldGroup/withFields.public' import { createAppFormInitializer } from './initializeAppForm.lib' import { useFormContext } from './contexts.lib' -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AppFormHookResult, CreateFormHookOptions, UseAppFormHook, } from './createFormHookTypes.public' import type { Component } from 'vue' -import type { FormOptions } from '@tanstack/form-core' +import type { FormOptions, FormOptionsApi } from '@tanstack/form-core' -const appFormOptions = ((opts: unknown) => opts) as AppFormOptionsApi +const appFormOptions = ((opts: unknown) => opts) as FormOptionsApi appFormOptions.strictSchema = (opts) => opts as never appFormOptions.looseSchema = (opts) => opts as never @@ -26,7 +25,7 @@ export function createFormHook< }> { const initializeAppForm = createAppFormInitializer(createOptions) - function useExtendedForm(options: FormOptions) { + function useExtendedForm(options: FormOptions) { return useInternalForm(options, initializeAppForm) } diff --git a/packages/vue-form/src/AppForm/createFormHookTypes.public.ts b/packages/vue-form/src/AppForm/createFormHookTypes.public.ts index 3195a4f4f0..88805e4cd0 100644 --- a/packages/vue-form/src/AppForm/createFormHookTypes.public.ts +++ b/packages/vue-form/src/AppForm/createFormHookTypes.public.ts @@ -1,4 +1,3 @@ -import type { AppFormOptionsApi } from './appFormOptions.public' import type { AnyVueFormComponentMap, VueFormComponentMap, @@ -11,6 +10,7 @@ import type { DefaultFormGroupOptions, DefaultFormOptions, FormOptions, + FormOptionsApi, FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' @@ -100,7 +100,7 @@ export type UseAppFormHook = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => VueAppFormApi< TFormData, ToFormErrorTypes, @@ -108,7 +108,7 @@ export type UseAppFormHook = < > export interface AppFormHookResult { - appFormOptions: AppFormOptionsApi + appFormOptions: FormOptionsApi defineAppFieldGroup: DefineFieldGroupFn useAppForm: UseAppFormHook useFormContext: () => VueAppFormApi diff --git a/packages/vue-form/src/AppForm/initializeAppForm.lib.ts b/packages/vue-form/src/AppForm/initializeAppForm.lib.ts index f256ea80bf..25d02623cc 100644 --- a/packages/vue-form/src/AppForm/initializeAppForm.lib.ts +++ b/packages/vue-form/src/AppForm/initializeAppForm.lib.ts @@ -20,7 +20,7 @@ interface AnyCreateFormHookOptions { export function createAppFormInitializer( createOptions: AnyCreateFormHookOptions, -): (options: FormOptions) => InternalVueFormApi { +): (options: FormOptions) => InternalVueFormApi { const hasDefaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || diff --git a/packages/vue-form/src/VueForm/VueFormApi.lib.ts b/packages/vue-form/src/VueForm/VueFormApi.lib.ts index b00b14a6b7..c766b3ea2f 100644 --- a/packages/vue-form/src/VueForm/VueFormApi.lib.ts +++ b/packages/vue-form/src/VueForm/VueFormApi.lib.ts @@ -9,14 +9,16 @@ export interface InternalVueFormApi extends AnyInternalFormApi, VueTanStackFormComponents {} export function initializeForm( - options: FormOptions, + options: FormOptions, ): InternalVueFormApi { return attachVueFormComponents(new InternalFormApi(options), null) } export function useInternalForm( - options: FormOptions, - initializeFn: (options: FormOptions) => InternalVueFormApi, + options: FormOptions, + initializeFn: ( + options: FormOptions, + ) => InternalVueFormApi, ) { const vueFormId = useId() const resolveOptions = () => diff --git a/packages/vue-form/src/VueForm/formType.public.ts b/packages/vue-form/src/VueForm/formType.public.ts index 34d7da0c67..323d407884 100644 --- a/packages/vue-form/src/VueForm/formType.public.ts +++ b/packages/vue-form/src/VueForm/formType.public.ts @@ -4,7 +4,6 @@ import type { FormValidators, ToFormErrorTypes, } from '@tanstack/form-core' -import type { AppFormOptions } from '../AppForm/appFormOptions.public' import type { AnyVueFormComponentMap, DefaultVueFormComponentMap, @@ -41,11 +40,8 @@ type VueFormTypeErrorTypes< * * @typeParam TOptions - The reusable form or app-form options from which the API derives its form data, error, and registered-component types. */ -export type VueFormType< - TOptions extends - AnyFormOptions | AppFormOptions, -> = - TOptions extends AppFormOptions< +export type VueFormType = + TOptions extends FormOptions< infer TFormData, infer TFormValidators, infer TSubmitReturn, @@ -54,16 +50,8 @@ export type VueFormType< ? VueFormApi< TFormData, VueFormTypeErrorTypes, - TComponents + TComponents extends AnyVueFormComponentMap + ? TComponents + : DefaultVueFormComponentMap > - : TOptions extends FormOptions< - infer TFormData, - infer TFormValidators, - infer TSubmitReturn - > - ? VueFormApi< - TFormData, - VueFormTypeErrorTypes, - DefaultVueFormComponentMap - > - : never + : never diff --git a/packages/vue-form/src/VueForm/useForm.public.ts b/packages/vue-form/src/VueForm/useForm.public.ts index b9d1349280..9a6a3d7670 100644 --- a/packages/vue-form/src/VueForm/useForm.public.ts +++ b/packages/vue-form/src/VueForm/useForm.public.ts @@ -15,14 +15,14 @@ export type UseFormHook = < const TFormValidators extends FormValidators, TSubmitReturn, >( - options: FormOptions, + options: FormOptions, ) => VueFormApi< TFormData, ToFormErrorTypes, TComponents > -function useFormHook(options: FormOptions) { +function useFormHook(options: FormOptions) { return useInternalForm(options, initializeForm) } diff --git a/packages/vue-form/src/index.ts b/packages/vue-form/src/index.ts index 1d7d4bbbe2..895b6696ac 100644 --- a/packages/vue-form/src/index.ts +++ b/packages/vue-form/src/index.ts @@ -9,7 +9,6 @@ export * from './Subscribe.public' export * from './FieldGroup/FieldGroupApi.public' export * from './FieldGroup/withFields.public' export * from './AppForm/VueAppFormApi.public' -export * from './AppForm/appFormOptions.public' export * from './AppForm/componentMap.public' export * from './AppForm/createFormHook.public' export * from './AppForm/createFormHookTypes.public'