@tanstack/form-core 0.23.2 → 0.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/FormApi.ts CHANGED
@@ -19,6 +19,9 @@ import type {
19
19
  Validator,
20
20
  } from './types'
21
21
 
22
+ /**
23
+ * @private
24
+ */
22
25
  export type FormValidateFn<
23
26
  TFormData,
24
27
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
@@ -27,6 +30,9 @@ export type FormValidateFn<
27
30
  formApi: FormApi<TFormData, TFormValidator>
28
31
  }) => ValidationError
29
32
 
33
+ /**
34
+ * @private
35
+ */
30
36
  export type FormValidateOrFn<
31
37
  TFormData,
32
38
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
@@ -34,6 +40,9 @@ export type FormValidateOrFn<
34
40
  ? TFN
35
41
  : FormValidateFn<TFormData, TFormValidator>
36
42
 
43
+ /**
44
+ * @private
45
+ */
37
46
  export type FormValidateAsyncFn<
38
47
  TFormData,
39
48
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
@@ -43,6 +52,9 @@ export type FormValidateAsyncFn<
43
52
  signal: AbortSignal
44
53
  }) => ValidationError | Promise<ValidationError>
45
54
 
55
+ /**
56
+ * @private
57
+ */
46
58
  export type FormAsyncValidateOrFn<
47
59
  TFormData,
48
60
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
@@ -54,17 +66,41 @@ export interface FormValidators<
54
66
  TFormData,
55
67
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
56
68
  > {
69
+ /**
70
+ * Optional function that fires as soon as the component mounts.
71
+ */
57
72
  onMount?: FormValidateOrFn<TFormData, TFormValidator>
73
+ /**
74
+ * Optional function that checks the validity of your data whenever a value changes
75
+ */
58
76
  onChange?: FormValidateOrFn<TFormData, TFormValidator>
77
+ /**
78
+ * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.
79
+ */
59
80
  onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>
81
+ /**
82
+ * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.
83
+ */
60
84
  onChangeAsyncDebounceMs?: number
85
+ /**
86
+ * Optional function that validates the form data when a field loses focus, returns a ValidationError
87
+ */
61
88
  onBlur?: FormValidateOrFn<TFormData, TFormValidator>
89
+ /**
90
+ * Optional onBlur asynchronous validation method for when a field loses focus return a `ValidationError` or a promise of `Promise<ValidationError>`
91
+ */
62
92
  onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>
93
+ /**
94
+ * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.
95
+ */
63
96
  onBlurAsyncDebounceMs?: number
64
97
  onSubmit?: FormValidateOrFn<TFormData, TFormValidator>
65
98
  onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>
66
99
  }
67
100
 
101
+ /**
102
+ * @private
103
+ */
68
104
  export interface FormTransform<
69
105
  TFormData,
70
106
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
@@ -75,20 +111,47 @@ export interface FormTransform<
75
111
  deps: unknown[]
76
112
  }
77
113
 
114
+ /**
115
+ * An object representing the options for a form.
116
+ */
78
117
  export interface FormOptions<
79
118
  TFormData,
80
119
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
81
120
  > {
121
+ /**
122
+ * Set initial values for your form.
123
+ */
82
124
  defaultValues?: TFormData
125
+ /**
126
+ * The default state for the form.
127
+ */
83
128
  defaultState?: Partial<FormState<TFormData>>
129
+ /**
130
+ * If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.
131
+ */
84
132
  asyncAlways?: boolean
133
+ /**
134
+ * Optional time in milliseconds if you want to introduce a delay before firing off an async action.
135
+ */
85
136
  asyncDebounceMs?: number
137
+ /**
138
+ * A validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)
139
+ */
86
140
  validatorAdapter?: TFormValidator
141
+ /**
142
+ * A list of validators to pass to the form
143
+ */
87
144
  validators?: FormValidators<TFormData, TFormValidator>
145
+ /**
146
+ * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`
147
+ */
88
148
  onSubmit?: (props: {
89
149
  value: TFormData
90
150
  formApi: FormApi<TFormData, TFormValidator>
91
151
  }) => any | Promise<any>
152
+ /**
153
+ * Specify an action for scenarios where the user tries to submit an invalid form.
154
+ */
92
155
  onSubmitInvalid?: (props: {
93
156
  value: TFormData
94
157
  formApi: FormApi<TFormData, TFormValidator>
@@ -96,44 +159,113 @@ export interface FormOptions<
96
159
  transform?: FormTransform<TFormData, TFormValidator>
97
160
  }
98
161
 
162
+ /**
163
+ * An object representing the validation metadata for a field. Not intended for public usage.
164
+ */
99
165
  export type ValidationMeta = {
166
+ /**
167
+ * An abort controller stored in memory to cancel previous async validation attempts.
168
+ */
100
169
  lastAbortController: AbortController
101
170
  }
102
171
 
172
+ /**
173
+ * An object representing the field information for a specific field within the form.
174
+ */
103
175
  export type FieldInfo<
104
176
  TFormData,
105
177
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
106
178
  > = {
179
+ /**
180
+ * An instance of the FieldAPI.
181
+ */
107
182
  instance: FieldApi<
108
183
  TFormData,
109
184
  any,
110
185
  Validator<unknown, unknown> | undefined,
111
186
  TFormValidator
112
187
  > | null
188
+ /**
189
+ * A record of field validation internal handling.
190
+ */
113
191
  validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>
114
192
  }
115
193
 
194
+ /**
195
+ * An object representing the current state of the form.
196
+ */
116
197
  export type FormState<TFormData> = {
198
+ /**
199
+ * The current values of the form fields.
200
+ */
117
201
  values: TFormData
118
- // Form Validation
202
+ /**
203
+ * A boolean indicating if the form is currently validating.
204
+ */
119
205
  isFormValidating: boolean
206
+ /**
207
+ * A boolean indicating if the form is valid.
208
+ */
120
209
  isFormValid: boolean
210
+ /**
211
+ * The error array for the form itself.
212
+ */
121
213
  errors: ValidationError[]
214
+ /**
215
+ * The error map for the form itself.
216
+ */
122
217
  errorMap: ValidationErrorMap
218
+ /**
219
+ * An internal mechanism used for keeping track of validation logic in a form.
220
+ */
123
221
  validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>
124
- // Fields
222
+ /**
223
+ * A record of field metadata for each field in the form.
224
+ */
125
225
  fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>
226
+ /**
227
+ * A boolean indicating if any of the form fields are currently validating.
228
+ */
126
229
  isFieldsValidating: boolean
230
+ /**
231
+ * A boolean indicating if all the form fields are valid.
232
+ */
127
233
  isFieldsValid: boolean
234
+ /**
235
+ * A boolean indicating if the form is currently submitting.
236
+ */
128
237
  isSubmitting: boolean
129
- // General
238
+ /**
239
+ * A boolean indicating if any of the form fields have been touched.
240
+ */
130
241
  isTouched: boolean
242
+ /**
243
+ * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.
244
+ */
131
245
  isDirty: boolean
246
+ /**
247
+ * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.
248
+ */
132
249
  isPristine: boolean
250
+ /**
251
+ * A boolean indicating if the form has been submitted.
252
+ */
133
253
  isSubmitted: boolean
254
+ /**
255
+ * A boolean indicating if the form or any of its fields are currently validating.
256
+ */
134
257
  isValidating: boolean
258
+ /**
259
+ * A boolean indicating if the form and all its fields are valid.
260
+ */
135
261
  isValid: boolean
262
+ /**
263
+ * A boolean indicating if the form can be submitted based on its current state.
264
+ */
136
265
  canSubmit: boolean
266
+ /**
267
+ * A counter for tracking the number of submission attempts.
268
+ */
137
269
  submissionAttempts: number
138
270
  }
139
271
 
@@ -168,21 +300,60 @@ function getDefaultFormState<TFormData>(
168
300
  }
169
301
  }
170
302
 
303
+ /**
304
+ * A class representing the Form API. It handles the logic and interactions with the form state.
305
+ *
306
+ * Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework
307
+ * hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.
308
+ * However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.
309
+ */
171
310
  export class FormApi<
172
311
  TFormData,
173
312
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
174
313
  > {
314
+ /**
315
+ * The options for the form.
316
+ */
175
317
  options: FormOptions<TFormData, TFormValidator> = {}
318
+ /**
319
+ * A [TanStack Store instance](https://tanstack.com/store/latest/docs/reference/Store) that keeps track of the form's state.
320
+ */
176
321
  store!: Store<FormState<TFormData>>
177
- // Do not use __state directly, as it is not reactive.
178
- // Please use form.useStore() utility to subscribe to state
322
+ /**
323
+ * The current state of the form.
324
+ *
325
+ * **Note:**
326
+ * Do not use `state` directly, as it is not reactive.
327
+ * Please use form.useStore() utility to subscribe to state
328
+ */
179
329
  state!: FormState<TFormData>
180
- // // This carries the context for nested fields
330
+ /**
331
+ * A record of field information for each field in the form.
332
+ */
181
333
  fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =
182
334
  {} as any
183
335
 
336
+ /**
337
+ * @private
338
+ */
184
339
  prevTransformArray: unknown[] = []
185
340
 
341
+ /**
342
+ * @private
343
+ * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are
344
+ * subsequently generated from the `pushFieldValue` (and friends)
345
+ * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607
346
+ */
347
+ _tempDefaultValue:
348
+ | undefined
349
+ | {
350
+ field: string
351
+ value: unknown
352
+ } = undefined
353
+
354
+ /**
355
+ * Constructs a new `FormApi` instance with the given form options.
356
+ */
186
357
  constructor(opts?: FormOptions<TFormData, TFormValidator>) {
187
358
  this.store = new Store<FormState<TFormData>>(
188
359
  getDefaultFormState({
@@ -260,6 +431,9 @@ export class FormApi<
260
431
  this.update(opts || {})
261
432
  }
262
433
 
434
+ /**
435
+ * @private
436
+ */
263
437
  runValidator<
264
438
  TValue extends { value: TFormData; formApi: FormApi<any, any> },
265
439
  TType extends 'validate' | 'validateAsync',
@@ -297,6 +471,9 @@ export class FormApi<
297
471
  }
298
472
  }
299
473
 
474
+ /**
475
+ * Updates the form options and form state.
476
+ */
300
477
  update = (options?: FormOptions<TFormData, TFormValidator>) => {
301
478
  if (!options) return
302
479
 
@@ -334,6 +511,9 @@ export class FormApi<
334
511
  })
335
512
  }
336
513
 
514
+ /**
515
+ * Resets the form state to the default values.
516
+ */
337
517
  reset = () => {
338
518
  const { fieldMeta: currentFieldMeta } = this.state
339
519
  const fieldMeta = this.resetFieldMeta(currentFieldMeta)
@@ -346,6 +526,9 @@ export class FormApi<
346
526
  )
347
527
  }
348
528
 
529
+ /**
530
+ * Validates all fields in the form using the correct handlers for a given validation type.
531
+ */
349
532
  validateAllFields = async (cause: ValidationCause) => {
350
533
  const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any
351
534
  this.store.batch(() => {
@@ -370,6 +553,9 @@ export class FormApi<
370
553
  return fieldErrorMapMap.flat()
371
554
  }
372
555
 
556
+ /**
557
+ * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.
558
+ */
373
559
  validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(
374
560
  field: TField,
375
561
  index: number,
@@ -406,6 +592,9 @@ export class FormApi<
406
592
  return fieldErrorMapMap.flat()
407
593
  }
408
594
 
595
+ /**
596
+ * Validates a specified field in the form using the correct handlers for a given validation type.
597
+ */
409
598
  validateField = <TField extends DeepKeys<TFormData>>(
410
599
  field: TField,
411
600
  cause: ValidationCause,
@@ -423,7 +612,10 @@ export class FormApi<
423
612
  return fieldInstance.validate(cause)
424
613
  }
425
614
 
426
- // TODO: This code is copied from FieldApi, we should refactor to share
615
+ /**
616
+ * TODO: This code is copied from FieldApi, we should refactor to share
617
+ * @private
618
+ */
427
619
  validateSync = (cause: ValidationCause) => {
428
620
  const validates = getSyncValidatorArray(cause, this.options)
429
621
  let hasErrored = false as boolean
@@ -480,6 +672,9 @@ export class FormApi<
480
672
  return { hasErrored }
481
673
  }
482
674
 
675
+ /**
676
+ * @private
677
+ */
483
678
  validateAsync = async (
484
679
  cause: ValidationCause,
485
680
  ): Promise<ValidationError[]> => {
@@ -561,6 +756,9 @@ export class FormApi<
561
756
  return results.filter(Boolean)
562
757
  }
563
758
 
759
+ /**
760
+ * @private
761
+ */
564
762
  validate = (
565
763
  cause: ValidationCause,
566
764
  ): ValidationError[] | Promise<ValidationError[]> => {
@@ -575,12 +773,10 @@ export class FormApi<
575
773
  return this.validateAsync(cause)
576
774
  }
577
775
 
776
+ /**
777
+ * Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.
778
+ */
578
779
  handleSubmit = async () => {
579
- // Check to see that the form and all fields have been touched
580
- // If they have not, touch them all and run validation
581
- // Run form validation
582
- // Submit the form
583
-
584
780
  this.store.setState((old) => ({
585
781
  ...old,
586
782
  // Submission attempts mark the form as not submitted
@@ -637,16 +833,25 @@ export class FormApi<
637
833
  }
638
834
  }
639
835
 
836
+ /**
837
+ * Gets the value of the specified field.
838
+ */
640
839
  getFieldValue = <TField extends DeepKeys<TFormData>>(
641
840
  field: TField,
642
841
  ): DeepValue<TFormData, TField> => getBy(this.state.values, field)
643
842
 
843
+ /**
844
+ * Gets the metadata of the specified field.
845
+ */
644
846
  getFieldMeta = <TField extends DeepKeys<TFormData>>(
645
847
  field: TField,
646
848
  ): FieldMeta | undefined => {
647
849
  return this.state.fieldMeta[field]
648
850
  }
649
851
 
852
+ /**
853
+ * Gets the field info of the specified field.
854
+ */
650
855
  getFieldInfo = <TField extends DeepKeys<TFormData>>(
651
856
  field: TField,
652
857
  ): FieldInfo<TFormData, TFormValidator> => {
@@ -663,6 +868,9 @@ export class FormApi<
663
868
  })
664
869
  }
665
870
 
871
+ /**
872
+ * Updates the metadata of the specified field.
873
+ */
666
874
  setFieldMeta = <TField extends DeepKeys<TFormData>>(
667
875
  field: TField,
668
876
  updater: Updater<FieldMeta>,
@@ -699,6 +907,9 @@ export class FormApi<
699
907
  )
700
908
  }
701
909
 
910
+ /**
911
+ * Sets the value of the specified field and optionally updates the touched state.
912
+ */
702
913
  setFieldValue = <TField extends DeepKeys<TFormData>>(
703
914
  field: TField,
704
915
  updater: Updater<DeepValue<TFormData, TField>>,
@@ -735,6 +946,9 @@ export class FormApi<
735
946
  delete this.fieldInfo[field]
736
947
  }
737
948
 
949
+ /**
950
+ * Pushes a value into an array field.
951
+ */
738
952
  pushFieldValue = <TField extends DeepKeys<TFormData>>(
739
953
  field: TField,
740
954
  value: DeepValue<TFormData, TField> extends any[]
@@ -742,6 +956,12 @@ export class FormApi<
742
956
  : never,
743
957
  opts?: { touch?: boolean },
744
958
  ) => {
959
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
960
+ const fieldVal = (this.getFieldValue(field) as unknown[]) ?? []
961
+ this._tempDefaultValue = {
962
+ value,
963
+ field: `${field}[${fieldVal.length}]`,
964
+ } as never
745
965
  this.setFieldValue(
746
966
  field,
747
967
  (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,
@@ -750,6 +970,9 @@ export class FormApi<
750
970
  this.validateField(field, 'change')
751
971
  }
752
972
 
973
+ /**
974
+ * Inserts a value into an array field at the specified index, shifting the subsequent values to the right.
975
+ */
753
976
  insertFieldValue = async <TField extends DeepKeys<TFormData>>(
754
977
  field: TField,
755
978
  index: number,
@@ -758,6 +981,7 @@ export class FormApi<
758
981
  : never,
759
982
  opts?: { touch?: boolean },
760
983
  ) => {
984
+ this._tempDefaultValue = { value, field: `${field}[${index}]` } as never
761
985
  this.setFieldValue(
762
986
  field,
763
987
  (prev) => {
@@ -774,6 +998,9 @@ export class FormApi<
774
998
  await this.validateField(field, 'change')
775
999
  }
776
1000
 
1001
+ /**
1002
+ * Replaces a value into an array field at the specified index.
1003
+ */
777
1004
  replaceFieldValue = async <TField extends DeepKeys<TFormData>>(
778
1005
  field: TField,
779
1006
  index: number,
@@ -782,6 +1009,7 @@ export class FormApi<
782
1009
  : never,
783
1010
  opts?: { touch?: boolean },
784
1011
  ) => {
1012
+ this._tempDefaultValue = { value, field: `${field}[${index}]` } as never
785
1013
  this.setFieldValue(
786
1014
  field,
787
1015
  (prev) => {
@@ -797,6 +1025,9 @@ export class FormApi<
797
1025
  await this.validateArrayFieldsStartingFrom(field, index, 'change')
798
1026
  }
799
1027
 
1028
+ /**
1029
+ * Removes a value from an array field at the specified index.
1030
+ */
800
1031
  removeFieldValue = async <TField extends DeepKeys<TFormData>>(
801
1032
  field: TField,
802
1033
  index: number,
@@ -833,6 +1064,9 @@ export class FormApi<
833
1064
  await this.validateArrayFieldsStartingFrom(field, index, 'change')
834
1065
  }
835
1066
 
1067
+ /**
1068
+ * Swaps the values at the specified indices within an array field.
1069
+ */
836
1070
  swapFieldValues = <TField extends DeepKeys<TFormData>>(
837
1071
  field: TField,
838
1072
  index1: number,
@@ -856,6 +1090,9 @@ export class FormApi<
856
1090
  this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')
857
1091
  }
858
1092
 
1093
+ /**
1094
+ * Moves the value at the first specified index to the second specified index within an array field.
1095
+ */
859
1096
  moveFieldValues = <TField extends DeepKeys<TFormData>>(
860
1097
  field: TField,
861
1098
  index1: number,
package/src/mergeForm.ts CHANGED
@@ -2,6 +2,9 @@ import type { FormApi } from './FormApi'
2
2
  import type { Validator } from './types'
3
3
  import type { NoInfer } from './util-types'
4
4
 
5
+ /**
6
+ * @private
7
+ */
5
8
  export function mutateMergeDeep(target: object, source: object): object {
6
9
  const targetKeys = Object.keys(target)
7
10
  const sourceKeys = Object.keys(source)
package/src/types.ts CHANGED
@@ -1,16 +1,28 @@
1
1
  export type ValidationError = undefined | false | null | string
2
2
 
3
- // If/when TypeScript supports higher-kinded types, this should not be `unknown` anymore
3
+ /**
4
+ * If/when TypeScript supports higher-kinded types, this should not be `unknown` anymore
5
+ * @private
6
+ */
4
7
  export type Validator<Type, Fn = unknown> = () => {
5
8
  validate(options: { value: Type }, fn: Fn): ValidationError
6
9
  validateAsync(options: { value: Type }, fn: Fn): Promise<ValidationError>
7
10
  }
8
11
 
9
- // "server" is only intended for SSR/SSG validation and should not execute anything
12
+ /**
13
+ * "server" is only intended for SSR/SSG validation and should not execute anything
14
+ * @private
15
+ */
10
16
  export type ValidationCause = 'change' | 'blur' | 'submit' | 'mount' | 'server'
11
17
 
18
+ /**
19
+ * @private
20
+ */
12
21
  export type ValidationErrorMapKeys = `on${Capitalize<ValidationCause>}`
13
22
 
23
+ /**
24
+ * @private
25
+ */
14
26
  export type ValidationErrorMap = {
15
27
  [K in ValidationErrorMapKeys]?: ValidationError
16
28
  }
package/src/util-types.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  type Nullable<T> = T | null
2
2
  type IsNullable<T> = [null] extends [T] ? true : false
3
3
 
4
+ /**
5
+ * @private
6
+ */
4
7
  export type RequiredByKey<T, K extends keyof T> = Omit<T, K> &
5
8
  Required<Pick<T, K>>
6
9
 
@@ -13,13 +16,22 @@ type NarrowRaw<A> =
13
16
  [K in keyof A]: A[K] extends Function ? A[K] : NarrowRaw<A[K]>
14
17
  }
15
18
 
19
+ /**
20
+ * @private
21
+ */
16
22
  export type NoInfer<T> = [T][T extends any ? 0 : never]
17
23
 
24
+ /**
25
+ * @private
26
+ */
18
27
  export type Narrow<A> = Try<A, [], NarrowRaw<A>>
19
28
 
20
29
  type Try<A1, A2, Catch = never> = A1 extends A2 ? A1 : Catch
21
30
 
22
- // Hack to get TypeScript to show simplified types in error messages
31
+ /**
32
+ * Hack to get TypeScript to show simplified types in error messages
33
+ * @private
34
+ */
23
35
  export type Pretty<T> = { [K in keyof T]: T[K] } & {}
24
36
 
25
37
  type ComputeRange<
@@ -67,6 +79,9 @@ type PrefixObjectAccessor<T extends object, TDepth extends any[]> = {
67
79
  : never
68
80
  }[keyof T]
69
81
 
82
+ /**
83
+ * The keys of an object or array, deeply nested.
84
+ */
70
85
  export type DeepKeys<T, TDepth extends any[] = []> = TDepth['length'] extends 5
71
86
  ? never
72
87
  : unknown extends T
@@ -89,9 +104,8 @@ type PrefixFromDepth<
89
104
  > = TDepth['length'] extends 0 ? T : `.${T}`
90
105
 
91
106
  /**
92
- Infer the type of a deeply nested property within an object or an array.
93
- See the tests in `util-types.test-d.ts` for usage.
94
- */
107
+ * Infer the type of a deeply nested property within an object or an array.
108
+ */
95
109
  export type DeepValue<
96
110
  // The object or array in which we have the property whose type we're trying to infer
97
111
  TValue,