Skip to content

Commit ebc2200

Browse files
authored
Merge 3fb88ef into a1523e2
2 parents a1523e2 + 3fb88ef commit ebc2200

File tree

3 files changed

+40
-37
lines changed

3 files changed

+40
-37
lines changed

src/namePathType.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,26 @@ export type DeepNamePath<
1313
? ParentNamePath['length'] extends 0
1414
? Store | BaseNamePath // Return `BaseNamePath` instead of array if `ParentNamePath` is empty
1515
: Store extends any[]
16-
? [...ParentNamePath, number] // Connect path
16+
? readonly [...ParentNamePath, number] // Connect path
1717
: never
1818
: Store extends any[] // Check if `Store` is `any[]`
1919
? // Connect path. e.g. { a: { b: string }[] }
2020
// Get: [a] | [ a,number] | [ a ,number , b]
21-
[...ParentNamePath, number] | DeepNamePath<Store[number], [...ParentNamePath, number]>
21+
readonly [...ParentNamePath, number] | DeepNamePath<Store[number], [...ParentNamePath, number]>
2222
: {
2323
// Convert `Store` to <key, value>. We mark key a `FieldKey`
2424
[FieldKey in keyof Store]: Store[FieldKey] extends Function
2525
? never
2626
:
2727
| (ParentNamePath['length'] extends 0 ? FieldKey : never) // If `ParentNamePath` is empty, it can use `FieldKey` without array path
28-
| [...ParentNamePath, FieldKey] // Exist `ParentNamePath`, connect it
28+
| readonly [...ParentNamePath, FieldKey] // Exist `ParentNamePath`, connect it
2929
| DeepNamePath<Required<Store>[FieldKey], [...ParentNamePath, FieldKey]>; // If `Store[FieldKey]` is object
3030
}[keyof Store];
31+
32+
export type GetNameType<
33+
Store = any,
34+
NamePath extends readonly any[] = [],
35+
NamePathCache extends readonly any[] = [],
36+
> = NamePathCache['length'] extends NamePath['length']
37+
? Store
38+
: GetNameType<Store[NamePath[NamePathCache['length']]], NamePath, [...NamePathCache, true]>;

src/useWatch.ts

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
import { useState, useContext, useEffect, useRef, useMemo } from 'react';
1212
import { getNamePath, getValue } from './utils/valueUtil';
1313
import { isFormInstance } from './utils/typeUtil';
14+
import type { DeepNamePath, GetNameType } from './namePathType';
1415

1516
type ReturnPromise<T> = T extends Promise<infer ValueType> ? ValueType : never;
1617
type GetGeneric<TForm extends FormInstance> = ReturnPromise<ReturnType<TForm['validateFields']>>;
@@ -37,39 +38,15 @@ const useWatchWarning =
3738
: () => {};
3839

3940
function useWatch<
40-
TDependencies1 extends keyof GetGeneric<TForm>,
41-
TForm extends FormInstance,
42-
TDependencies2 extends keyof GetGeneric<TForm>[TDependencies1],
43-
TDependencies3 extends keyof GetGeneric<TForm>[TDependencies1][TDependencies2],
44-
TDependencies4 extends keyof GetGeneric<TForm>[TDependencies1][TDependencies2][TDependencies3],
41+
TForm extends FormInstance = FormInstance,
42+
const TDependencies extends DeepNamePath<GetGeneric<TForm>> = any,
4543
>(
46-
dependencies: [TDependencies1, TDependencies2, TDependencies3, TDependencies4],
44+
dependencies: TDependencies,
4745
form?: TForm | WatchOptions<TForm>,
48-
): GetGeneric<TForm>[TDependencies1][TDependencies2][TDependencies3][TDependencies4];
49-
50-
function useWatch<
51-
TDependencies1 extends keyof GetGeneric<TForm>,
52-
TForm extends FormInstance,
53-
TDependencies2 extends keyof GetGeneric<TForm>[TDependencies1],
54-
TDependencies3 extends keyof GetGeneric<TForm>[TDependencies1][TDependencies2],
55-
>(
56-
dependencies: [TDependencies1, TDependencies2, TDependencies3],
57-
form?: TForm | WatchOptions<TForm>,
58-
): GetGeneric<TForm>[TDependencies1][TDependencies2][TDependencies3];
59-
60-
function useWatch<
61-
TDependencies1 extends keyof GetGeneric<TForm>,
62-
TForm extends FormInstance,
63-
TDependencies2 extends keyof GetGeneric<TForm>[TDependencies1],
64-
>(
65-
dependencies: [TDependencies1, TDependencies2],
66-
form?: TForm | WatchOptions<TForm>,
67-
): GetGeneric<TForm>[TDependencies1][TDependencies2];
68-
69-
function useWatch<TDependencies extends keyof GetGeneric<TForm>, TForm extends FormInstance>(
70-
dependencies: TDependencies | [TDependencies],
71-
form?: TForm | WatchOptions<TForm>,
72-
): GetGeneric<TForm>[TDependencies];
46+
): GetNameType<
47+
GetGeneric<TForm>,
48+
TDependencies extends readonly any[] ? TDependencies : [TDependencies]
49+
>;
7350

7451
function useWatch<TForm extends FormInstance>(
7552
dependencies: [],

tests/useWatch.test.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ describe('useWatch', () => {
258258
demo?: string;
259259
demo2?: string;
260260
id?: number;
261-
demo1?: { demo2?: { demo3?: { demo4?: string } } };
261+
demo1?: { demo2?: { demo3?: { demo4?: { demo5?: { demo6: { demo7?: string } } } } } };
262262
};
263263

264264
const Demo: React.FC = () => {
@@ -271,10 +271,28 @@ describe('useWatch', () => {
271271
const demo3 = Form.useWatch(['demo1', 'demo2', 'demo3'], form);
272272
const demo4 = Form.useWatch(['demo1', 'demo2', 'demo3', 'demo4'], form);
273273
const demo5 = Form.useWatch(['demo1', 'demo2', 'demo3', 'demo4', 'demo5'], form);
274-
const more = Form.useWatch(['age', 'name', 'gender'], form);
274+
const demo6 = Form.useWatch(['demo1', 'demo2', 'demo3', 'demo4', 'demo5', 'demo6'], form);
275+
const demo7 = Form.useWatch(
276+
['demo1', 'demo2', 'demo3', 'demo4', 'demo5', 'demo6', 'demo7'],
277+
form,
278+
);
275279
const demo = Form.useWatch<string>(['demo']);
276280
return (
277-
<>{JSON.stringify({ values, main, age, demo1, demo2, demo3, demo4, demo5, more, demo })}</>
281+
<>
282+
{JSON.stringify({
283+
values,
284+
main,
285+
age,
286+
demo1,
287+
demo2,
288+
demo3,
289+
demo4,
290+
demo5,
291+
demo6,
292+
demo7,
293+
demo,
294+
})}
295+
</>
278296
);
279297
};
280298

0 commit comments

Comments
 (0)