@@ -189,24 +189,22 @@ export default function normalizeFields< Item >(
189189
190190 const filterBy = getFilterBy ( field , fieldTypeDefinition ) ;
191191
192- let format = { } ;
193- if ( field . type === 'date' ) {
194- format = {
195- date :
196- field . format ?. date !== undefined &&
197- typeof field . format . date === 'string'
198- ? field . format . date
199- : getSettings ( ) . formats . date ,
200- weekStartsOn : DAYS_OF_WEEK . includes (
201- field . format ?. weekStartsOn as DayString
202- )
203- ? field ?. format ?. weekStartsOn
204- : numberToWeekStartsOn ( getSettings ( ) . l10n . startOfWeek ) ,
205- } ;
206- }
207-
208- return {
209- ...field ,
192+ /**
193+ * NormalizedField is a discriminated union type: the shape of the format property
194+ * depends on the type property. For example, for the 'date' type, the format
195+ * contains date or weekStartsOn — which are not valid for other types.
196+ *
197+ * Being type and format interdependent, we need to write the code
198+ * in a way that TypeScript is able to statically infer the types.
199+ * That's why we have a return branch for every item in the union type.
200+ *
201+ * See a longer explanation with examples at
202+ * https://github.com/WordPress/gutenberg/pull/72999#discussion_r2523145453
203+ */
204+ const { type, ...fieldWithoutType } = field ;
205+
206+ const baseField = {
207+ ...fieldWithoutType ,
210208 label : field . label || field . id ,
211209 header : field . header || field . label || field . id ,
212210 getValue,
@@ -223,7 +221,30 @@ export default function normalizeFields< Item >(
223221 true ,
224222 filterBy,
225223 readOnly : field . readOnly ?? fieldTypeDefinition . readOnly ?? false ,
226- format,
224+ format : { } ,
227225 } ;
226+
227+ if ( field . type === 'date' ) {
228+ const format = {
229+ date :
230+ field . format ?. date !== undefined &&
231+ typeof field . format . date === 'string'
232+ ? field . format . date
233+ : getSettings ( ) . formats . date ,
234+ weekStartsOn : DAYS_OF_WEEK . includes (
235+ field . format ?. weekStartsOn as DayString
236+ )
237+ ? field ?. format ?. weekStartsOn
238+ : numberToWeekStartsOn ( getSettings ( ) . l10n . startOfWeek ) ,
239+ } ;
240+
241+ return {
242+ ...baseField ,
243+ type : 'date' ,
244+ format,
245+ } ;
246+ }
247+
248+ return { ...baseField , type : field . type , format : { } } ;
228249 } ) ;
229250}
0 commit comments