Skip to content

Commit fd5d380

Browse files
author
erikras-gilfoyle-agent
committed
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.
1 parent f25a24e commit fd5d380

2 files changed

Lines changed: 213 additions & 0 deletions

File tree

MIGRATION_V7.md

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