@@ -800,8 +800,8 @@ export function isDirty(
800800 } ;
801801
802802 return ! deepEqual (
803- normalize ( formValue , serialize ) ,
804- normalize ( options ?. defaultValue , serialize ) ,
803+ normalize ( formValue , { serialize } ) ,
804+ normalize ( options ?. defaultValue , { serialize } ) ,
805805 ) ;
806806}
807807
@@ -891,21 +891,28 @@ export function defaultSerialize(value: unknown): ReturnType<Serialize> {
891891}
892892
893893/**
894- * Recursively serializes a value using the provided serialize function,
895- * collapsing empty leaves (`null`, `''` , empty files) to `undefined`
896- * and removing empty containers (objects with no remaining keys, empty arrays) .
894+ * Recursively serializes a value using the provided serialize function.
895+ * When `stripEmptyValue` is true, empty values , empty arrays, and empty objects
896+ * are removed, and single-string arrays are unwrapped to match single-value fields .
897897 *
898898 * When serialize returns `undefined` for a value (i.e. it can't be represented
899899 * as form data), the raw value is kept and recursed into if it's an object or array.
900900 *
901- * Single-element arrays where the element is a string or undefined are unwrapped
902- * to handle the case where a multi-value field (e.g. checkboxes) has only one value.
903901 */
904902export function normalize (
905903 value : unknown ,
906- serialize : Serialize = defaultSerialize ,
907- name ?: string ,
904+ options : {
905+ serialize ?: Serialize ;
906+ stripEmptyValue ?: boolean ;
907+ name ?: string ;
908+ } = { } ,
908909) : unknown {
910+ const {
911+ serialize = defaultSerialize ,
912+ stripEmptyValue = true ,
913+ name,
914+ } = options ;
915+
909916 let data : unknown = serialize ( value , {
910917 name,
911918 } ) ;
@@ -914,28 +921,29 @@ export function normalize(
914921 data = value ;
915922 }
916923
917- if ( data === '' || data === null ) {
924+ if ( stripEmptyValue && ( data === null || data === '' ) ) {
918925 return undefined ;
919926 }
920927
921928 if ( isGlobalInstance ( data , 'File' ) ) {
922- if ( data . name === '' && data . size === 0 ) {
929+ if ( stripEmptyValue && data . name === '' && data . size === 0 ) {
923930 return undefined ;
924931 }
925932
926933 return data ;
927934 }
928935
929936 if ( Array . isArray ( data ) ) {
930- if ( data . length === 0 ) {
937+ if ( stripEmptyValue && data . length === 0 ) {
931938 return undefined ;
932939 }
933940
934941 const array = data . map ( ( item , index ) =>
935- normalize ( item , serialize , appendPath ( name , index ) ) ,
942+ normalize ( item , { ... options , name : appendPath ( name , index ) } ) ,
936943 ) ;
937944
938945 if (
946+ stripEmptyValue &&
939947 array . length === 1 &&
940948 ( typeof array [ 0 ] === 'string' || array [ 0 ] === undefined )
941949 ) {
@@ -948,11 +956,10 @@ export function normalize(
948956 if ( isPlainObject ( data ) ) {
949957 const entries = Object . entries ( data ) . reduce < Array < [ string , unknown ] > > (
950958 ( list , [ key , value ] ) => {
951- const normalizedValue = normalize (
952- value ,
953- serialize ,
954- appendPath ( name , key ) ,
955- ) ;
959+ const normalizedValue = normalize ( value , {
960+ ...options ,
961+ name : appendPath ( name , key ) ,
962+ } ) ;
956963
957964 if ( typeof normalizedValue !== 'undefined' ) {
958965 list . push ( [ key , normalizedValue ] ) ;
@@ -963,7 +970,7 @@ export function normalize(
963970 [ ] ,
964971 ) ;
965972
966- if ( entries . length === 0 ) {
973+ if ( stripEmptyValue && entries . length === 0 ) {
967974 return undefined ;
968975 }
969976
0 commit comments