Description
There is a type mismatch between the runtime implementation and type definition of the errors field in FormApi.ts. The runtime code filters out undefined values from the error map, but the type definition does not exclude undefined, causing type errors.
Current Behavior
Runtime Implementation (Lines 1056-1074):
fieldErrors = Object.values(currBaseMeta.errorMap ?? {}).filter(
(val) => val !== undefined,
) as never
The code explicitly filters out undefined values from the errorMap.
Type Definition (Lines 686-700):
errors: Array<
| UnwrapFormValidateOrFn<TOnMount>
| UnwrapFormValidateOrFn<TOnChange>
| UnwrapFormAsyncValidateOrFn<TOnChangeAsync>
// ... other types
| UnwrapFormAsyncValidateOrFn<TOnServer>
>
However, the type definition doesn't reflect that undefined values are filtered out, which can potentially include undefined in the union types.
Expected Behavior
The errors type definition should use NonNullable or explicitly exclude undefined to match the runtime behavior:
errors: Array<
NonNullable<
| UnwrapFormValidateOrFn<TOnMount>
| UnwrapFormValidateOrFn<TOnChange>
| UnwrapFormAsyncValidateOrFn<TOnChangeAsync>
// ... other types
| UnwrapFormAsyncValidateOrFn<TOnServer>
>
>
References
Proposed Solution
Wrap the error type union with NonNullable<> to ensure the type system reflects that undefined values are filtered out at runtime.
Your minimal, reproducible example
https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wChRJZFiYARAeQFk5tcCj0YBaAE1wHo0AG2BIAdjDIVo8AN5wArgGckAMWh4Avixx58AARgoxSo2gDW-Dhi6YNZUmggn4ABSQQwQpK5QBzJDgAXjgACgBKYIA+OFlSOAS4JxcWDWDFFXUoEFC4xPy4HiRMFAUhGAA1FCEFJCUALlj4gpblJCgxFBAkRvx8ABpmlvz-HrgABkHhuE0p4ecAZQUAIxBgGEbcuAA3atqZyKCYvOnE-n44Wgg4JVwkGAALYDE-OAB3dYfU7MKUIyHTtV2jBQgApBb0AByADpTFBnn5gJgAJ6hXY1JD9OBiMpCLEAJnC4QB+VmAM0xIBRBgCg6YRJiQAPHZstDVKIhDwGS1Ot0ggAiUb87kFdHAHh-aBKIKyE6nArnOAAdUCaGMSQeEAgKjgy3ubyQ4m+IC4HyKcGMPBYHJ4XCUYCQaCRwDQO2q4slUCUIumzgAwg9jAFNvJ0fsKdEffK3Ri4DEAIwAZjgAH5FGIiphnkgrb1GMp4Hq4Em4NBS5z2gMowlNJpqxrgJyiGIZaEs0hOYcYqF6-lGVFe8NGc8wAoYIP5bykDL25zoVO69GlzHajObbCjDAkNCw0hF8v5c4AEI1KBrjs8aGBjPeE+0-cH6YwZEOgU4kB6qDCx+nf3XgKtkgXbWheV6Wt4AZBkgoTbkYUABDAO57EgACCSiQgoH7tOED4-nA-ADnhiSyAAhLOl6mH827dEY0LAEoVQiFaABkzH0kRLSMvQYhCMiCwwPCLwAKJQDgXpwO0YnSrI5EblR0I0Sg0KSVK2gEROBQ4RpjLqUuWnTLpiTEnWjjOKYcDcbx-GCX4IlSY0yCcGyfqMvIKleo0cIIgA2gAujMMQhFs7lKAc0RNPk1K0mIcCMiIhHDLIIUKSgYChDBonQMBcXAHA5hIMiMruZoURJZlUCaDp8X6Uy-DxaQJnJOZOAQDAQneN0EjpHwaCYeIiEIe1SCdTAR7IgAkjwoSEFqkjhCRpCORgDCMNCaAcFuCCzaELVtR1-XhNCzZFFAoSMu4njeL4AT4VE4RAA
Steps to reproduce
Reproduction Steps
Step 1: Define validator functions that return string | undefined
const validateOnChange = (value: string): string | undefined => {
return value.length < 3 ? 'Too short' : undefined;
};
const validateOnBlur = (value: string): string | undefined => {
return value.includes('@') ? undefined : 'Must include @';
};
Step 2: Observe the errors type definition
The errors array type includes undefined in its union:
type ErrorsType = Array<
| string
| undefined // ← undefined is included
>;
Step 3: Runtime behavior filters out undefined
At runtime (lines 1056-1074 in FormApi.ts), the code explicitly filters undefined:
fieldErrors = Object.values(currBaseMeta.errorMap ?? {}).filter(
(val) => val !== undefined,
) as never
Step 4: Type mismatch occurs
When you try to use the errors array assuming it doesn't contain undefined:
// TypeScript error: Object is possibly 'undefined'
errors.forEach(error => {
console.log(error.length); // ❌ Type error
});
// You're forced to check for undefined even though runtime filters it
errors.forEach(error => {
if (error !== undefined) { // ✅ Unnecessary runtime check
console.log(error.length);
}
});
Expected behavior
Expected Behavior
The errors type definition should use NonNullable to exclude undefined and match the runtime behavior:
errors: Array<
NonNullable<
| UnwrapFormValidateOrFn<TOnMount>
| UnwrapFormValidateOrFn<TOnChange>
| UnwrapFormAsyncValidateOrFn<TOnChangeAsync>
| UnwrapFormValidateOrFn<TOnBlur>
| UnwrapFormAsyncValidateOrFn<TOnBlurAsync>
| UnwrapFormValidateOrFn<TOnSubmit>
| UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>
| UnwrapFormValidateOrFn<TOnDynamic>
| UnwrapFormAsyncValidateOrFn<TOnDynamicAsync>
| UnwrapFormAsyncValidateOrFn<TOnServer>
>
>
This would align the type system with the runtime implementation that filters out undefined values.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
N/A - This is a TypeScript type definition issue that occurs at compile-time, not runtime. It affects the type checking process regardless of operating system or browser.
TanStack Form adapter
react-form
TanStack Form version
v1.28.0
TypeScript version
v5.9.3
Additional context
No response
Description
There is a type mismatch between the runtime implementation and type definition of the
errorsfield inFormApi.ts. The runtime code filters outundefinedvalues from the error map, but the type definition does not excludeundefined, causing type errors.Current Behavior
Runtime Implementation (Lines 1056-1074):
The code explicitly filters out
undefinedvalues from the errorMap.Type Definition (Lines 686-700):
However, the type definition doesn't reflect that
undefinedvalues are filtered out, which can potentially includeundefinedin the union types.Expected Behavior
The
errorstype definition should useNonNullableor explicitly excludeundefinedto match the runtime behavior:References
Proposed Solution
Wrap the error type union with
NonNullable<>to ensure the type system reflects thatundefinedvalues are filtered out at runtime.Your minimal, reproducible example
https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wChRJZFiYARAeQFk5tcCj0YBaAE1wHo0AG2BIAdjDIVo8AN5wArgGckAMWh4Avixx58AARgoxSo2gDW-Dhi6YNZUmggn4ABSQQwQpK5QBzJDgAXjgACgBKYIA+OFlSOAS4JxcWDWDFFXUoEFC4xPy4HiRMFAUhGAA1FCEFJCUALlj4gpblJCgxFBAkRvx8ABpmlvz-HrgABkHhuE0p4ecAZQUAIxBgGEbcuAA3atqZyKCYvOnE-n44Wgg4JVwkGAALYDE-OAB3dYfU7MKUIyHTtV2jBQgApBb0AByADpTFBnn5gJgAJ6hXY1JD9OBiMpCLEAJnC4QB+VmAM0xIBRBgCg6YRJiQAPHZstDVKIhDwGS1Ot0ggAiUb87kFdHAHh-aBKIKyE6nArnOAAdUCaGMSQeEAgKjgy3ubyQ4m+IC4HyKcGMPBYHJ4XCUYCQaCRwDQO2q4slUCUIumzgAwg9jAFNvJ0fsKdEffK3Ri4DEAIwAZjgAH5FGIiphnkgrb1GMp4Hq4Em4NBS5z2gMowlNJpqxrgJyiGIZaEs0hOYcYqF6-lGVFe8NGc8wAoYIP5bykDL25zoVO69GlzHajObbCjDAkNCw0hF8v5c4AEI1KBrjs8aGBjPeE+0-cH6YwZEOgU4kB6qDCx+nf3XgKtkgXbWheV6Wt4AZBkgoTbkYUABDAO57EgACCSiQgoH7tOED4-nA-ADnhiSyAAhLOl6mH827dEY0LAEoVQiFaABkzH0kRLSMvQYhCMiCwwPCLwAKJQDgXpwO0YnSrI5EblR0I0Sg0KSVK2gEROBQ4RpjLqUuWnTLpiTEnWjjOKYcDcbx-GCX4IlSY0yCcGyfqMvIKleo0cIIgA2gAujMMQhFs7lKAc0RNPk1K0mIcCMiIhHDLIIUKSgYChDBonQMBcXAHA5hIMiMruZoURJZlUCaDp8X6Uy-DxaQJnJOZOAQDAQneN0EjpHwaCYeIiEIe1SCdTAR7IgAkjwoSEFqkjhCRpCORgDCMNCaAcFuCCzaELVtR1-XhNCzZFFAoSMu4njeL4AT4VE4RAA
Steps to reproduce
Reproduction Steps
Step 1: Define validator functions that return
string | undefinedStep 2: Observe the
errorstype definitionThe
errorsarray type includesundefinedin its union:Step 3: Runtime behavior filters out
undefinedAt runtime (lines 1056-1074 in FormApi.ts), the code explicitly filters
undefined:Step 4: Type mismatch occurs
When you try to use the
errorsarray assuming it doesn't containundefined:Expected behavior
Expected Behavior
The
errorstype definition should useNonNullableto excludeundefinedand match the runtime behavior:This would align the type system with the runtime implementation that filters out
undefinedvalues.How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
N/A - This is a TypeScript type definition issue that occurs at compile-time, not runtime. It affects the type checking process regardless of operating system or browser.
TanStack Form adapter
react-form
TanStack Form version
v1.28.0
TypeScript version
v5.9.3
Additional context
No response