Skip to content

Commit ab46e1e

Browse files
erikras-gilfoyle-agenterikras-gilfoyle-agenterikras-dinesh-agent
authored
docs: Add v7.0.0 migration guide for TypeScript users (#1064)
* docs: Add v7.0.0 migration guide for TypeScript users Addresses #1054 Creates comprehensive migration guide documenting TypeScript-specific breaking changes when upgrading from v6 to v7: - FormState properties now optional (dirty, pristine, valid, etc.) - FieldMetaState type no longer exported - AnyObject type no longer exported - UseFieldConfig no longer generic - FormProps no longer accepts arbitrary props Also includes final-form v5.0.0 changes and migration strategy. Updates README with link to migration guide. * docs: Add blank lines around code blocks (MD031) --------- Co-authored-by: erikras-gilfoyle-agent <gilfoyle@openclaw.local> Co-authored-by: erikras-dinesh-agent <dinesh@openclaw.dev>
1 parent 5509a15 commit ab46e1e

2 files changed

Lines changed: 228 additions & 0 deletions

File tree

MIGRATION_V7.md

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Migration Guide: react-final-form v6 → v7
2+
3+
## Overview
4+
5+
Version 7.0.0 includes a complete TypeScript rewrite (migrated from Flow). While the runtime behavior remains largely unchanged, there are several TypeScript-specific breaking changes you need to be aware of.
6+
7+
## Breaking Changes
8+
9+
### 1. FormState Properties Now Optional
10+
11+
In v7.0.0, most FormState boolean properties can be `undefined`:
12+
13+
**❌ Before (v6.x):**
14+
15+
```typescript
16+
const { dirty, pristine, valid } = formState;
17+
if (dirty && !pristine) { // Works fine
18+
// ...
19+
}
20+
```
21+
22+
**✅ After (v7.0.0):**
23+
24+
```typescript
25+
const { dirty, pristine, valid } = formState;
26+
if ((dirty ?? false) && !(pristine ?? true)) { // Must handle undefined
27+
// ...
28+
}
29+
```
30+
31+
**Affected properties:**
32+
- `dirty`, `pristine`, `valid`, `invalid`
33+
- `dirtySinceLastSubmit`, `modifiedSinceLastSubmit`
34+
- `submitFailed`, `submitSucceeded`, `submitting`, `validating`
35+
- `hasSubmitErrors`, `hasValidationErrors`
36+
37+
**Note:** `values` is still guaranteed to be defined.
38+
39+
### 2. FieldMetaState Type No Longer Exported
40+
41+
**❌ Before (v6.x):**
42+
43+
```typescript
44+
import { FieldMetaState } from 'react-final-form';
45+
46+
const meta: FieldMetaState = { /* ... */ };
47+
```
48+
49+
**✅ After (v7.0.0):**
50+
51+
```typescript
52+
import { FieldRenderProps } from 'react-final-form';
53+
54+
const meta: FieldRenderProps<any>['meta'] = { /* ... */ };
55+
56+
// Or define it locally:
57+
type FieldMetaState = {
58+
active?: boolean;
59+
data?: Record<string, any>;
60+
dirty?: boolean;
61+
// ... etc
62+
};
63+
```
64+
65+
### 3. AnyObject Type No Longer Exported
66+
67+
**❌ Before (v6.x):**
68+
69+
```typescript
70+
import { AnyObject } from 'react-final-form';
71+
```
72+
73+
**✅ After (v7.0.0):**
74+
75+
```typescript
76+
// Define locally:
77+
type AnyObject = Record<string, any>;
78+
```
79+
80+
### 4. UseFieldConfig No Longer Generic
81+
82+
**❌ Before (v6.x):**
83+
84+
```typescript
85+
const config: UseFieldConfig<string> = {
86+
validate: (value) => value ? undefined : 'Required'
87+
};
88+
```
89+
90+
**✅ After (v7.0.0):**
91+
92+
```typescript
93+
const config: UseFieldConfig = {
94+
validate: (value) => value ? undefined : 'Required'
95+
};
96+
```
97+
98+
### 5. FormProps No Longer Accepts Arbitrary Props
99+
100+
In v6.x, you could pass arbitrary props (like `style`, `className`) directly to `<Form>`. In v7.0.0, this is no longer supported due to stricter TypeScript typing.
101+
102+
**❌ Before (v6.x):**
103+
104+
```tsx
105+
<Form
106+
onSubmit={handleSubmit}
107+
style={{ padding: '20px' }}
108+
className="my-form"
109+
>
110+
{/* ... */}
111+
</Form>
112+
```
113+
114+
**✅ After (v7.0.0):**
115+
116+
```tsx
117+
<Form onSubmit={handleSubmit}>
118+
{({ handleSubmit }) => (
119+
<form onSubmit={handleSubmit} style={{ padding: '20px' }} className="my-form">
120+
{/* ... */}
121+
</form>
122+
)}
123+
</Form>
124+
125+
// Or wrap in a div:
126+
<div style={{ padding: '20px' }} className="my-form">
127+
<Form onSubmit={handleSubmit}>
128+
{/* ... */}
129+
</Form>
130+
</div>
131+
```
132+
133+
## final-form v5.0.0 Changes
134+
135+
If you're also upgrading final-form to v5.0.0, be aware of these changes:
136+
137+
### 1. InternalFormState Requires asyncErrors
138+
139+
**❌ Before (v4.x):**
140+
141+
```typescript
142+
const mockFormState: InternalFormState = {
143+
values: {},
144+
// ...
145+
};
146+
```
147+
148+
**✅ After (v5.0.0):**
149+
150+
```typescript
151+
const mockFormState: InternalFormState = {
152+
values: {},
153+
asyncErrors: {}, // Now required
154+
// ...
155+
};
156+
```
157+
158+
### 2. Mutator Type Signature Changed
159+
160+
**❌ Before (v4.x):**
161+
162+
```typescript
163+
const mutator: Mutator = (args, state, tools) => {
164+
// ...
165+
};
166+
```
167+
168+
**✅ After (v5.0.0):**
169+
170+
```typescript
171+
// If you get type errors with existing mutators:
172+
const mutator = ((args, state, tools) => {
173+
// ...
174+
}) as unknown as Mutator;
175+
```
176+
177+
## Migration Strategy
178+
179+
For a medium to large codebase, expect to modify 100+ files. Here's a recommended approach:
180+
181+
1. **Update dependencies:**
182+
183+
```bash
184+
npm install react-final-form@^7.0.0 final-form@^5.0.0
185+
```
186+
187+
2. **Fix compilation errors in this order:**
188+
- Handle optional boolean properties (use `?? false` or `?? true`)
189+
- Replace `FieldMetaState` imports with `FieldRenderProps['meta']`
190+
- Replace `AnyObject` imports with local type definition
191+
- Remove generic from `UseFieldConfig<T>``UseFieldConfig`
192+
- Fix `<Form>` props (move styling to wrapper or inner `<form>`)
193+
194+
3. **Test thoroughly:**
195+
- All form submissions
196+
- Validation behavior
197+
- Field state management
198+
- Meta information display
199+
200+
4. **Update mocks/tests:**
201+
- Add `asyncErrors: {}` to InternalFormState mocks
202+
- Cast mutators if needed
203+
204+
## Need Help?
205+
206+
If you encounter issues during migration:
207+
208+
1. Check the [TypeScript examples](https://github.com/final-form/react-final-form/tree/main/examples/typescript)
209+
2. Review [closed issues](https://github.com/final-form/react-final-form/issues?q=is%3Aissue+typescript)
210+
3. Open a [new issue](https://github.com/final-form/react-final-form/issues/new) with a reproduction
211+
212+
## Benefits of v7.0.0
213+
214+
Despite the migration effort, v7.0.0 brings significant benefits:
215+
216+
- **Better TypeScript support** - First-class TypeScript instead of generated types from Flow
217+
- **Improved type inference** - Better autocomplete and type checking
218+
- **Modern codebase** - Easier for contributors to work with
219+
- **Long-term maintainability** - TypeScript ecosystem is more active than Flow
220+
221+
---
222+
223+
**Version**: 7.0.0
224+
**Last Updated**: 2026-02-13

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ React Final Form is a thin React wrapper for [Final Form](https://final-form.org
3939

4040
## [Getting Started](https://final-form.org/docs/react-final-form/getting-started)
4141

42+
## 🔄 Upgrading from v6 to v7?
43+
44+
See the [Migration Guide](./MIGRATION_V7.md) for TypeScript-specific breaking changes and how to handle them.
45+
4246
## [Philosophy](https://final-form.org/docs/react-final-form/philosophy)
4347

4448
## [Examples](https://final-form.org/docs/react-final-form/examples)

0 commit comments

Comments
 (0)