-
-
Notifications
You must be signed in to change notification settings - Fork 541
Description
Describe the bug
Typescript definitions are incorrect.
Your minimal, reproducible example
no sandbox
Steps to reproduce
`"use client";
import React from "react";
import {
createFormFactory,
FormApi,
mergeForm,
useTransform,
} from "@tanstack/react-form";
import { Input } from "../ui/input";
import { Label } from "../ui/label";
import { Button } from "../ui/button";
import { useFormState } from "react-dom";
const todos = [
{
id: 1,
name: "Buy milk",
},
{
id: 2,
name: "Drink water",
},
{
id: 3,
name: "Eat food",
},
{
id: 4,
name: "Go out",
},
];
const TodoList = () => {
const formFactory = createFormFactory({
defaultValues: {
firstName: "Sergiu",
todos: todos,
},
});
const [state, action] = useFormState(() => {}, formFactory.initialFormState);
// ts error here: Argument of type 'Partial<FormState<{ firstName: string; todos: { id: number; name: string; }[]; }>>' is not assignable to parameter of type 'void'.
const { Provider, Field, handleSubmit, Subscribe, useStore } =
formFactory.useForm({
transform: useTransform(
(baseForm: FormApi<any, any>) => mergeForm(baseForm, state),
// ts error here, state: Argument of type 'void' is not assignable to parameter of type 'Partial<FormState>'
[state]
),
onSubmit: async ({ value }) => {
console.log(value);
},
});
return (
<form
action={action as never}
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
void handleSubmit();
}}
>
<Field
name="firstName"
children={(field) => {
return (
<>
First Name:
<Input
id="firstName"
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
className="border rounded"
/>
</>
);
}}
/>
<Field
name="todos"
mode="array"
children={({ state, pushValue, removeValue }) => {
return (
<>
<Button
type="button"
onClick={() => {
pushValue({
id: state.value.length + 1,
name: "",
});
}}
>
Create new board
{state.value.map((board, i) => {
return (
<Field
index={i} // Type 'number' is not assignable to type 'undefined'.
name={
name} // Type '"name"' is not assignable to type '"firstName" | "todos" | "todos.name" | "todos.id"'.children={(field) => {
return (
{field.name}:{" "}
<Input
id={field.name}
name={field.name}
value={field.state.value} // Type 'unknown' is not assignable to type 'string | number | readonly string[] | undefined'.
onBlur={field.handleBlur}
onChange={(e) =>
field.handleChange(e.target.value)
}
className="border rounded"
/>
<Button
type="button"
onClick={() => removeValue(i)}
>
remove
);
}}
/>
);
})}
</>
);
}}
/>
<Subscribe
selector={(state) => [state.canSubmit, state.isSubmitting]}
children={([canSubmit, isSubmittig]) => {
return (
{isSubmittig ? "..." : "Submit"}
);
}}
/>
);
};
export default TodoList;
`
Expected behavior
I expect errors from myself not library.
How often does this bug happen?
Every time
Screenshots or Videos
"use client";
import React from "react";
import {
createFormFactory,
FormApi,
mergeForm,
useTransform,
} from "@tanstack/react-form";
import { Input } from "../ui/input";
import { Label } from "../ui/label";
import { Button } from "../ui/button";
import { useFormState } from "react-dom";
const todos = [
{
id: 1,
name: "Buy milk",
},
{
id: 2,
name: "Drink water",
},
{
id: 3,
name: "Eat food",
},
{
id: 4,
name: "Go out",
},
];
const TodoList = () => {
const formFactory = createFormFactory({
defaultValues: {
firstName: "Sergiu",
todos: todos,
},
});
const [state, action] = useFormState(() => {}, formFactory.initialFormState);
const { Provider, Field, handleSubmit, Subscribe, useStore } =
formFactory.useForm({
transform: useTransform(
(baseForm: FormApi<any, any>) => mergeForm(baseForm, state),
[state]
),
onSubmit: async ({ value }) => {
console.log(value);
},
});
return (
<form
action={action as never}
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
void handleSubmit();
}}
>
<Field
name="firstName"
children={(field) => {
return (
<>
First Name:
<Input
id="firstName"
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
className="border rounded"
/>
</>
);
}}
/>
<Field
name="todos"
mode="array"
children={({ state, pushValue, removeValue }) => {
return (
<>
<Button
type="button"
onClick={() => {
pushValue({
id: state.value.length + 1,
name: "",
});
}}
>
Create new board
{state.value.map((board, i) => {
return (
<Field
index={i}
name={
name}children={(field) => {
return (
{field.name}:{" "}
<Input
id={field.name}
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) =>
field.handleChange(e.target.value)
}
className="border rounded"
/>
<Button
type="button"
onClick={() => removeValue(i)}
>
remove
);
}}
/>
);
})}
</>
);
}}
/>
<Subscribe
selector={(state) => [state.canSubmit, state.isSubmitting]}
children={([canSubmit, isSubmittig]) => {
return (
{isSubmittig ? "..." : "Submit"}
);
}}
/>
);
};
export default TodoList;
Platform
Next.js 14
MacOS m1
Tanstack Form adapter
react-form
TanStack Form version
0.13.3
TypeScript version
5.3.3
Additional context
No response