Skip to content

Commit c0aad3c

Browse files
authored
fix: strongly types field validation args (#8263)
Continuation of #8243. Strongly types the `value` argument within `field.validate` functions: - Uses existing internal validation types for field `validate` property - Exports additional validation types to cover `hasMany` fields - Includes `null` and `undefined` values
1 parent 110fda7 commit c0aad3c

File tree

4 files changed

+110
-28
lines changed

4 files changed

+110
-28
lines changed

packages/payload/src/fields/config/types.ts

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,33 @@ import type {
104104
} from '../../config/types.js'
105105
import type { DBIdentifierName } from '../../database/types.js'
106106
import type { SanitizedGlobalConfig } from '../../globals/config/types.js'
107-
import type { CollectionSlug } from '../../index.js'
107+
import type {
108+
ArrayFieldValidation,
109+
BlocksFieldValidation,
110+
CheckboxFieldValidation,
111+
CodeFieldValidation,
112+
CollectionSlug,
113+
DateFieldValidation,
114+
EmailFieldValidation,
115+
JSONFieldValidation,
116+
PointFieldValidation,
117+
RadioFieldValidation,
118+
TextareaFieldValidation,
119+
} from '../../index.js'
108120
import type { DocumentPreferences } from '../../preferences/types.js'
109121
import type { Operation, PayloadRequest, RequestContext, Where } from '../../types/index.js'
122+
import type {
123+
NumberFieldManyValidation,
124+
NumberFieldSingleValidation,
125+
RelationshipFieldManyValidation,
126+
RelationshipFieldSingleValidation,
127+
SelectFieldManyValidation,
128+
SelectFieldSingleValidation,
129+
TextFieldManyValidation,
130+
TextFieldSingleValidation,
131+
UploadFieldManyValidation,
132+
UploadFieldSingleValidation,
133+
} from '../validations.js'
110134

111135
export type FieldHookArgs<TData extends TypeWithID = any, TValue = any, TSiblingData = any> = {
112136
/** The collection which the field belongs to. If the field belongs to a global, this will be null. */
@@ -335,7 +359,7 @@ export type Validate<
335359
TSiblingData = any,
336360
TFieldConfig extends object = object,
337361
> = (
338-
value: TValue,
362+
value: null | TValue | undefined,
339363
options: ValidateOptions<TData, TSiblingData, TFieldConfig, TValue>,
340364
) => Promise<string | true> | string | true
341365

@@ -452,7 +476,7 @@ export type NumberField = {
452476
maxRows?: number
453477
/** Minimum number of numbers in the numbers array, if `hasMany` is set to true. */
454478
minRows?: number
455-
validate?: Validate<number[], unknown, unknown, NumberField>
479+
validate?: NumberFieldManyValidation
456480
}
457481
| {
458482
/** Makes this field an ordered array of numbers instead of just a single number. */
@@ -461,7 +485,7 @@ export type NumberField = {
461485
maxRows?: undefined
462486
/** Minimum number of numbers in the numbers array, if `hasMany` is set to true. */
463487
minRows?: undefined
464-
validate?: Validate<number, unknown, unknown, NumberField>
488+
validate?: NumberFieldSingleValidation
465489
}
466490
) &
467491
Omit<FieldBase, 'validate'>
@@ -502,7 +526,7 @@ export type TextField = {
502526
maxRows?: number
503527
/** Minimum number of strings in the strings array, if `hasMany` is set to true. */
504528
minRows?: number
505-
validate?: Validate<string[], unknown, unknown, TextField>
529+
validate?: TextFieldManyValidation
506530
}
507531
| {
508532
/** Makes this field an ordered array of strings instead of just a single string. */
@@ -511,7 +535,7 @@ export type TextField = {
511535
maxRows?: undefined
512536
/** Minimum number of strings in the strings array, if `hasMany` is set to true. */
513537
minRows?: undefined
514-
validate?: Validate<string, unknown, unknown, TextField>
538+
validate?: TextFieldSingleValidation
515539
}
516540
) &
517541
Omit<FieldBase, 'validate'>
@@ -541,7 +565,7 @@ export type EmailField = {
541565
placeholder?: Record<string, string> | string
542566
} & Admin
543567
type: 'email'
544-
validate?: Validate<string, unknown, unknown, EmailField>
568+
validate?: EmailFieldValidation
545569
} & Omit<FieldBase, 'validate'>
546570

547571
export type EmailFieldClient = {
@@ -572,7 +596,7 @@ export type TextareaField = {
572596
maxLength?: number
573597
minLength?: number
574598
type: 'textarea'
575-
validate?: Validate<string, unknown, unknown, TextareaField>
599+
validate?: TextareaFieldValidation
576600
} & Omit<FieldBase, 'validate'>
577601

578602
export type TextareaFieldClient = {
@@ -598,7 +622,7 @@ export type CheckboxField = {
598622
} & Admin['components']
599623
} & Admin
600624
type: 'checkbox'
601-
validate?: Validate<boolean, unknown, unknown, CheckboxField>
625+
validate?: CheckboxFieldValidation
602626
} & Omit<FieldBase, 'validate'>
603627

604628
export type CheckboxFieldClient = {
@@ -625,7 +649,7 @@ export type DateField = {
625649
placeholder?: Record<string, string> | string
626650
} & Admin
627651
type: 'date'
628-
validate?: Validate<unknown, unknown, unknown, DateField>
652+
validate?: DateFieldValidation
629653
} & Omit<FieldBase, 'validate'>
630654

631655
export type DateFieldClient = {
@@ -861,7 +885,7 @@ type SharedUploadProperties = {
861885
*/
862886
min?: number
863887
minRows?: number
864-
validate?: Validate<unknown[], unknown, unknown, SharedUploadProperties>
888+
validate?: UploadFieldManyValidation
865889
}
866890
| {
867891
hasMany?: false | undefined
@@ -875,7 +899,7 @@ type SharedUploadProperties = {
875899
*/
876900
min?: undefined
877901
minRows?: undefined
878-
validate?: Validate<unknown, unknown, unknown, SharedUploadProperties>
902+
validate?: UploadFieldSingleValidation
879903
}
880904
) &
881905
Omit<FieldBase, 'validate'>
@@ -950,7 +974,7 @@ export type CodeField = {
950974
maxLength?: number
951975
minLength?: number
952976
type: 'code'
953-
validate?: Validate<string, unknown, unknown, CodeField>
977+
validate?: CodeFieldValidation
954978
} & Omit<FieldBase, 'admin' | 'validate'>
955979

956980
export type CodeFieldClient = {
@@ -983,7 +1007,7 @@ export type JSONField = {
9831007
uri: string
9841008
}
9851009
type: 'json'
986-
validate?: Validate<Record<string, unknown>, unknown, unknown, JSONField>
1010+
validate?: JSONFieldValidation
9871011
} & Omit<FieldBase, 'admin' | 'validate'>
9881012

9891013
export type JSONFieldClient = {
@@ -1024,11 +1048,11 @@ export type SelectField = {
10241048
} & (
10251049
| {
10261050
hasMany: true
1027-
validate?: Validate<string[], unknown, unknown, SelectField>
1051+
validate?: SelectFieldManyValidation
10281052
}
10291053
| {
10301054
hasMany?: false | undefined
1031-
validate?: Validate<string, unknown, unknown, SelectField>
1055+
validate?: SelectFieldSingleValidation
10321056
}
10331057
) &
10341058
Omit<FieldBase, 'validate'>
@@ -1068,7 +1092,7 @@ type SharedRelationshipProperties = {
10681092
*/
10691093
min?: number
10701094
minRows?: number
1071-
validate?: Validate<any[], unknown, unknown, SharedRelationshipProperties>
1095+
validate?: RelationshipFieldManyValidation
10721096
}
10731097
| {
10741098
hasMany?: false | undefined
@@ -1082,7 +1106,7 @@ type SharedRelationshipProperties = {
10821106
*/
10831107
min?: undefined
10841108
minRows?: undefined
1085-
validate?: Validate<any, unknown, unknown, SharedRelationshipProperties>
1109+
validate?: RelationshipFieldSingleValidation
10861110
}
10871111
) &
10881112
Omit<FieldBase, 'validate'>
@@ -1155,11 +1179,11 @@ export function valueIsValueWithRelation(value: unknown): value is ValueWithRela
11551179
return value !== null && typeof value === 'object' && 'relationTo' in value && 'value' in value
11561180
}
11571181

1158-
export type RelationshipValue =
1159-
| (number | string)[]
1160-
| (number | string)
1161-
| ValueWithRelation
1162-
| ValueWithRelation[]
1182+
export type RelationshipValue = RelationshipValueMany | RelationshipValueSingle
1183+
1184+
export type RelationshipValueMany = (number | string)[] | ValueWithRelation[]
1185+
1186+
export type RelationshipValueSingle = number | string | ValueWithRelation
11631187

11641188
export type RichTextField<
11651189
TValue extends object = any,
@@ -1231,7 +1255,7 @@ export type ArrayField = {
12311255
maxRows?: number
12321256
minRows?: number
12331257
type: 'array'
1234-
validate?: Validate<unknown[], unknown, unknown, ArrayField>
1258+
validate?: ArrayFieldValidation
12351259
} & Omit<FieldBase, 'validate'>
12361260

12371261
export type ArrayFieldClient = {
@@ -1266,7 +1290,7 @@ export type RadioField = {
12661290
enumName?: DBIdentifierName
12671291
options: Option[]
12681292
type: 'radio'
1269-
validate?: Validate<string, unknown, unknown, RadioField>
1293+
validate?: RadioFieldValidation
12701294
} & Omit<FieldBase, 'validate'>
12711295

12721296
export type RadioFieldClient = {
@@ -1352,7 +1376,7 @@ export type BlocksField = {
13521376
maxRows?: number
13531377
minRows?: number
13541378
type: 'blocks'
1355-
validate?: Validate<string, unknown, unknown, BlocksField>
1379+
validate?: BlocksFieldValidation
13561380
} & Omit<FieldBase, 'validate'>
13571381

13581382
export type BlocksFieldClient = {
@@ -1379,7 +1403,7 @@ export type PointField = {
13791403
step?: number
13801404
} & Admin
13811405
type: 'point'
1382-
validate?: Validate<[number, number], unknown, unknown, PointField>
1406+
validate?: PointFieldValidation
13831407
} & Omit<FieldBase, 'validate'>
13841408

13851409
export type PointFieldClient = {

0 commit comments

Comments
 (0)