10000 :poop: improve type experience · vue-use-form/vue-use-form@752aea5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 752aea5

Browse files
committed
💩 improve type experience
1 parent 0509741 commit 752aea5

File tree

6 files changed

+99
-84
lines changed

6 files changed

+99
-84
lines changed

packages/core/src/logic/creatFormControl.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { getValidationMode } from '../utils/getValidationMode'
2020
import { isFieldElement } from '../utils/isFieldElement'
2121
import { warn } from '../utils/warn'
2222
import { handleValidateError, validateField } from './validate'
23+
import type { ResolverValues } from '../types/resolver'
24+
import type { FieldPath } from '../types/path'
2325
import type { RegisterOptions } from '../types/validator'
2426
import type { DefaultValues, UnpackNestedValue } from '../types/utils'
2527
import type {
@@ -46,7 +48,7 @@ import type { FieldError, FieldErrors } from '../types/errors'
4648
export function creatFormControl<
4749
TFieldValues extends FieldValues = FieldValues
4850
>(_options: Partial<UseFormProps<TFieldValues>>): UseFormReturn<TFieldValues> {
49-
type FieldsKey = keyof TFieldValues
51+
type FieldsKey = FieldPath<TFieldValues>
5052
type TFormState = FormState<TFieldValues>
5153
type TFormStateKey = keyof TFormState
5254

@@ -80,11 +82,14 @@ export function creatFormControl<
8082
}
8183
}
8284

83-
const _setFormStateError = (fieldName: FieldsKey, error: FieldError) => {
85+
const _setFormStateError = (
86+
fieldName: FieldsKey | string,
87+
error: FieldError
88+
) => {
8489
set(_formState.errors, fieldName, error)
8590
}
8691

87-
const _getFormStateError = (fieldName?: FieldsKey) =>
92+
const _getFormStateError = (fieldName?: FieldsKey | string) =>
8893
fieldName ? get(_formState.errors, fieldName) : _formState.errors
8994

9095
const isEmptyErrors = () => {
@@ -97,19 +102,22 @@ export function creatFormControl<
97102
return true
98103
}
99104

100-
const _removeFormStateError = (fieldName: FieldsKey) => {
105+
const _removeFormStateError = (fieldName: FieldsKey | string) => {
101106
if (isEmptyObject(_formState.errors)) {
102107
return
103108
}
104109

105110
unset(_formState.errors, fieldName)
106111
}
107112

108-
const _getField = (name: FieldsKey) => {
113+
const _getField = (name: FieldsKey | string) => {
109114
return get(_fields, name)
110115
}
111116

112-
const _setFields = (name: FieldsKey, fieldOptions: Partial<Field>) => {
117+
const _setFields = (
118+
name: FieldsKey | string,
119+
fieldOptions: Partial<Field>
120+
) => {
113121
// init field
114122
const field = _getField(name)
115123
if (isNullOrUndefined(field)) {
@@ -119,7 +127,7 @@ export function creatFormControl<
119127
set(_fields, name, { ...field, ...fieldOptions })
120128
}
121129

122-
const _getDefaultValue = (field: FieldsKey) => {
130+
const _getDefaultValue = (field: FieldsKey | string) => {
123131
return _defaultValues[field]
124132
}
125133

@@ -130,7 +138,7 @@ export function creatFormControl<
130138
return _getField(name).el.value as FieldElement | undefined
131139
}
132140

133-
const _isDirtyField = (fieldName: FieldsKey) => {
141+
const _isDirtyField = (fieldName: FieldsKey | string) => {
134142
const field = _getField(fieldName)
135143

136144
if (!field) {
@@ -187,7 +195,7 @@ export function creatFormControl<
187195
return dirtyFields
188196
}
189197

190-
const _handleDirtyField = (fieldName: FieldsKey) => {
198+
const _handleDirtyField = (fieldName: FieldsKey | string) => {
191199
const field = _getField(fieldName)
192200

193201
if (field.isUnregistered) {
@@ -237,7 +245,7 @@ export function creatFormControl<
237245
}
238246

239247
const _validate = async (
240-
fieldName: FieldsKey,
248+
fieldName: FieldsKey | string,
241249
isValidateAllFields = false
242250
) => {
243251
const field = _getField(fieldName)
@@ -290,10 +298,16 @@ export function creatFormControl<
290298
// resolver
291299
if (isFunction(resolver)) {
292300
const values = Object.fromEntries(
293-
Object.entries(_fields).map(([key, val]) => [key, val.inputValue.value])
301+
// TODO solve `any` type problem
302+
Object.entries(_fields).map(([key, val]) => [
303+
key,
304+
(val as any).inputValue.value,
305+
])
294306
)
295-
const errors = await resolver(values as Record<keyof TFieldValues, any>)
296-
if (!isEmptyObject(errors)) res = errors[fieldName] as FieldError
307+
const errors = await resolver(values as ResolverValues<FieldsKey>)
308+
if (!isEmptyObject(errors)) {
309+
res = errors[fieldName] as FieldError
310+
}
297311
} else {
298312
res = await validateField(
299313
field,
@@ -483,7 +497,10 @@ export function creatFormControl<
483497
}
484498
}
485499

486-
const _setFieldsValue = (name: FieldsKey, value: TFieldValues[FieldsKey]) => {
500+
const _setFieldsValue = (
501+
name: FieldsKey | string,
502+
value: TFieldValues[FieldsKey]
503+
) => {
487504
const field = _getField(name)
488505
const el = field.el.value
489506

@@ -494,7 +511,7 @@ export function creatFormControl<
494511
}
495512
}
496513

497-
const setValue: UseFormSetValue<TFieldValues, FieldsKey> = async (
514+
const setValue: UseFormSetValue<TFieldValues> = async (
498515
name,
499516
value,
500517
config = {}
@@ -529,7 +546,7 @@ export function creatFormControl<
529546
})
530547

531548
const getValues: UseFormGetValues<FieldValues, FieldsKey> = (fieldNames) => {
532-
const res: GetValuesReturn<FieldValues, FieldsKey> = {}
549+
const res: GetValuesReturn<FieldValues> = {}
533550

534551
if (isUndefined(fieldNames)) {
535552
for (const name of _originalFieldsKey.keys()) {
@@ -686,10 +703,7 @@ export function creatFormControl<
686703
}
687704

688705
if (!options.keepValue) {
689-
_setFieldsValue(
690-
fieldName as string,
691-
_defaultValues[fieldName] || ('' as any)
692-
)
706+
_setFieldsValue(fieldName, _defaultValues[fieldName] || ('' as any))
693707
}
694708

695709
_setFields(fieldName, {

packages/core/src/types/form.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
} from './utils'
1010
import type { FieldError, FieldErrors } from './errors'
1111
import type { RegisterOptions } from './validator'
12-
import type { FieldPath } from './path'
12+
import type { FieldPath, FieldPathValue } from './path'
1313

1414
export type Mode = 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all'
1515

@@ -67,11 +67,10 @@ export type UseFormClearErrors<FieldName> = (
6767
fieldName?: FieldName | FieldName[]
6868
) => void
6969

70-
export type GetValuesReturn<
71-
FieldValues,
72-
FieldVal = FieldValues[keyof FieldValues]
73-
> = {
74-
[K in keyof FieldValues]: FieldVal
70+
export type GetValuesReturn<TFieldValues extends FieldValues> = {
71+
[K in keyof TFieldValues]: TFieldValues[K] extends NestedValue<infer U>
72+
? U
73+
: TFieldValues[K]
7574
}
7675

7776
export type UseFormGetValues<FieldValues, FieldKeys> = (
@@ -94,22 +93,21 @@ export type UseFormSetError<FieldName> = (
9493
config?: { shouldFocusError: boolean }
9594
) => void
9695

97-
export type UseFormSetValue<
98-
FieldValues,
99-
FieldName extends keyof FieldValues,
100-
Value = FieldValues[FieldName]
101-
> = (
102-
name: FieldName,
103-
value: Value,
104-
config?: {
96+
export type UseFormSetValue<TFieldValues extends FieldValues> = <
97+
TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
98+
>(
99+
name: TFieldName,
100+
value: FieldPathValue<TFieldValues, TFieldName>,
101+
options?: {
105102
shouldValidate?: boolean
106103
shouldDirty?: boolean
107104
}
108105
) => Promise<void>
109106

110-
export type UseFormTriggerValidate<FieldKeys> = (
111-
fieldNames?: FieldKeys | FieldKeys[]
112-
) => Promise<void>
107+
export type UseFormTriggerValidate<
108+
TFieldValues extends FieldValues,
109+
FieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
110+
> = (fieldNames?: FieldName | FieldName[]) => Promise<void>
113111

114112
export type UseFormResetField<TFieldValues extends FieldValues> = <
115113
TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
@@ -131,8 +129,10 @@ export type UseFormReset<TFieldValues extends FieldValues> = (
131129
keepStateOptions?: KeepStateOptions
132130
) => void
133131

134-
export type UseFormUnregister<TFieldValues extends FieldValues> = (
135-
name?: keyof TFieldValues,
132+
export type UseFormUnregister<TFieldValues extends FieldValues> = <
133+
TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
134+
>(
135+
name?: TFieldName,
136136
options?: Omit<
137137
KeepStateOptions,
138138
| 'keepIsSubmitted'
@@ -163,9 +163,15 @@ export type UseFormRegister<TFieldValues extends FieldValues> = <
163163
options?: RegisterOptions<TFieldValues, TFieldName>
164164
) => any // UseFormRegisterReturn<TFieldName>
165165

166-
export type UseFormSetFocus<FieldName> = (name: FieldName) => void
166+
export type UseFormSetFocus<
167+
TFieldValues extends FieldValues,
168+
FieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
169+
> = (name: FieldName) => void
167170

168-
export type UseFormIsExistInErrors<FieldName> = (name: FieldName) => boolean
171+
export type UseFormIsExistInErrors<
172+
TFieldValues extends FieldValues,
173+
FieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
174+
> = (name: FieldName) => boolean
169175

170176
export interface UseFormHandlers<
171177
TFieldValues extends FieldValues,
@@ -175,7 +181,7 @@ export interface UseFormHandlers<
175181
getFieldState: UseFormGetFieldState<FieldName>
176182
setError: UseFormSetError<FieldName>
177183
clearErrors: UseFormClearErrors<FieldName>
178-
setValue: UseFormSetValue<TFieldValues, FieldName>
184+
setValue: UseFormSetValue<TFieldValues>
179185
triggerValidate: UseFormTriggerValidate<FieldName>
180186
reset: UseFormReset<TFieldValues>
181187
handleSubmit: UseFormHandleSubmit<TFieldValues>

packages/core/src/types/path/path.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export type PathValue<T, P extends Path<T> | ArrayPath<T>> = T extends any
113113
*/
114114
export type FieldPathValue<
115115
TFieldValues extends FieldValues,
116-
TFieldPath extends FieldPath<TFieldValues>
116+
TFieldPath extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
117117
> = PathValue<TFieldValues, TFieldPath>
118118

119119
/**

packages/core/src/types/resolver.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
import type { FieldValues } from './filed'
2+
import type { FieldPath } from './path'
13
import type { FieldErrors } from './errors'
24

35
export type ResolverResult<T> = FieldErrors<T>
46

5-
export type Resolver<FieldValues extends object> = (
6-
values: Record<keyof FieldValues, any>,
7+
export type ResolverValues<
8+
TFieldName extends FieldPath<FieldValues> = FieldPath<FieldValues>
9+
> = Record<TFieldName, any>
10+
11+
export type Resolver<TFieldValues extends FieldValues> = <
12+
FieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
13+
>(
14+
values: ResolverValues<FieldName>
715
) => Promise<ResolverResult<FieldValues>>

packages/core/src/types/validator.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import type { FieldPathValue } from './path'
12
import type { FieldValues } from './filed'
2-
import type { FieldPathValue } from './utils'
33

44
export type Message = string
55

@@ -14,43 +14,39 @@ export interface ValidationMode {
1414
export type ValidationValue = boolean | number | string | RegExp
1515

1616
export type ValidationRule<
17-
TValidationValue extends ValidationValue = ValidationValue,
18-
> = TValidationValue | ValidationValueMessage<TValidationValue>
17+
TValidationValue extends ValidationValue = ValidationValue
18+
> = TValidationValue | ValidationValueMessage<TValidationValue>
1919

2020
export interface ValidationValueMessage<
21-
TValidationValue extends ValidationValue = ValidationValue,
22-
> {
21+
TValidationValue extends ValidationValue = ValidationValue
22+
> {
2323
value: TValidationValue
2424
message: Message
2525
}
2626

2727
export type ValidateResult = Message | Message[] | boolean | undefined
2828

2929
export type Validate<TFieldValue> = (
30-
value: TFieldValue,
30+
value: TFieldValue
3131
) => ValidateResult | Promise<ValidateResult>
3232

33-
export type RegisterOptions<
34-
TFieldValues extends FieldValues = FieldValues,
35-
TFieldName extends string = string,
36-
> = Partial<{
37-
required: Message | ValidationRule<boolean>
38-
min: ValidationRule<number | string>
39-
max: ValidationRule<number | string>
40-
maxLength: ValidationRule<number>
41-
minLength: ValidationRule<number>
42-
pattern: ValidationRule<RegExp>
43-
validate:
44-
| Validate<FieldPathValue<TFieldValues, TFieldName>>
45-
| Record<string, Validate<FieldPathValue<TFieldValues, TFieldName>>>
46-
valueAsNumber: boolean
47-
valueAsDate: boolean
48-
value: FieldPathValue<TFieldValues, TFieldName>
49-
setValueAs: (value: any) => any
50-
vModelBinding?: string
51-
disabled?: boolean
52-
shouldUnregister?: boolean
53-
onChange?: (event: any) => void
54-
onBlur?: (event: any) => void
55-
}>
56-
33+
export type RegisterOptions<TFieldValues extends FieldValues> = Partial<{
34+
required: Message | ValidationRule<boolean>
35+
min: ValidationRule<number | string>
36+
max: ValidationRule<number | string>
37+
maxLength: ValidationRule<number>
38+
minLength: ValidationRule<number>
39+
pattern: ValidationRule<RegExp>
40+
validate:
41+
| Validate<FieldPathValue<TFieldValues>>
42+
| Record<string, Validate<FieldPathValue<TFieldValues>>>
43+
valueAsNumber: boolean
44+
valueAsDate: boolean
45+
value: FieldPathValue<TFieldValues>
46+
setValueAs: (value: any) => any
47+
vModelBinding?: string
48+
disabled?: boolean
49+
shouldUnregister?: boolean
50+
onChange?: (event: any) => void
51+
onBlur?: (event: any) => void
52+
}>

packages/core/src/useForm.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,3 @@ export function useForm<TFieldValues extends FieldValues = FieldValues>(
1818
...creatFormControl<TFieldValues>(props as UseFormProps<TFieldValues>),
1919
}
2020
}
21-
22-
// const { register, handleSubmit, formState, isExistInErrors } = useForm<{
23-
// user: {
24-
// name: string
25-
// data: { value: { data: string }[] }
26-
// }
27-
// }>()
28-
//
29-
// register('user.data[0].value[0].data')

0 commit comments

Comments
 (0)
0