@@ -21,7 +21,12 @@ import { Notice } from '@wordpress/components';
2121import classNames from 'classnames' ;
2222import { getSettingWithCoercion } from '@woocommerce/settings' ;
2323import { getQueryArgs , removeQueryArgs } from '@wordpress/url' ;
24- import { isBoolean , isString } from '@woocommerce/types' ;
24+ import {
25+ AttributeQuery ,
26+ isBoolean ,
27+ isString ,
28+ objectHasProp ,
29+ } from '@woocommerce/types' ;
2530import {
2631 PREFIX_QUERY_ARG_FILTER_TYPE ,
2732 PREFIX_QUERY_ARG_QUERY_TYPE ,
@@ -42,6 +47,7 @@ import {
4247 isQueryArgsEqual ,
4348 parseTaxonomyToGenerateURL ,
4449} from './utils' ;
50+ import { BlockAttributes , DisplayOption } from './types' ;
4551
4652/**
4753 * Formats filter values into a string for the URL parameters needed for filtering PHP templates.
@@ -62,6 +68,9 @@ import {
6268const AttributeFilterBlock = ( {
6369 attributes : blockAttributes ,
6470 isEditor = false ,
71+ } : {
72+ attributes : BlockAttributes ;
73+ isEditor ?: boolean ;
6574} ) => {
6675 const hasFilterableProducts = getSettingWithCoercion (
6776 'has_filterable_products' ,
@@ -93,7 +102,9 @@ const AttributeFilterBlock = ( {
93102 getActiveFilters ( filteringForPhpTemplate , attributeObject )
94103 ) ;
95104
96- const [ displayedOptions , setDisplayedOptions ] = useState (
105+ const [ displayedOptions , setDisplayedOptions ] = useState <
106+ DisplayOption [ ]
107+ > (
97108 blockAttributes . isPreview && ! blockAttributes . attributeId
98109 ? previewOptions
99110 : [ ]
@@ -119,7 +130,7 @@ const AttributeFilterBlock = ( {
119130 const { results : filteredCounts , isLoading : filteredCountsLoading } =
120131 useCollectionData ( {
121132 queryAttribute : {
122- taxonomy : attributeObject ?. taxonomy ,
133+ taxonomy : attributeObject ?. taxonomy || '' ,
123134 queryType : blockAttributes . queryType ,
124135 } ,
125136 queryState : {
@@ -133,7 +144,10 @@ const AttributeFilterBlock = ( {
133144 */
134145 const getFilteredTerm = useCallback (
135146 ( id ) => {
136- if ( ! filteredCounts . attribute_counts ) {
147+ if (
148+ ! objectHasProp ( filteredCounts , 'attribute_counts' ) ||
149+ ! Array . isArray ( filteredCounts . attribute_counts )
150+ ) {
137151 return null ;
138152 }
139153 return filteredCounts . attribute_counts . find (
@@ -152,13 +166,13 @@ const AttributeFilterBlock = ( {
152166 *
153167 * @param {string } termSlug The term of the slug to check.
154168 */
155- const isTermInQueryState = ( termSlug ) => {
169+ const isTermInQueryState = ( termSlug : string ) => {
156170 if ( ! queryState ?. attributes ) {
157171 return false ;
158172 }
159173 return queryState . attributes . some (
160- ( { attribute, slug = [ ] } ) =>
161- attribute === attributeObject . taxonomy &&
174+ ( { attribute, slug = [ ] } : AttributeQuery ) =>
175+ attribute === attributeObject ? .taxonomy &&
162176 slug . includes ( termSlug )
163177 ) ;
164178 } ;
@@ -167,6 +181,10 @@ const AttributeFilterBlock = ( {
167181 return ;
168182 }
169183
184+ if ( ! Array . isArray ( attributeTerms ) ) {
185+ return ;
186+ }
187+
170188 const newOptions = attributeTerms
171189 . map ( ( term ) => {
172190 const filteredTerm = getFilteredTerm ( term . id ) ;
@@ -193,7 +211,7 @@ const AttributeFilterBlock = ( {
193211 ) ,
194212 } ;
195213 } )
196- . filter ( Boolean ) ;
214+ . filter ( ( option ) : option is DisplayOption => ! ! option ) ;
197215
198216 setDisplayedOptions ( newOptions ) ;
199217 } , [
@@ -212,6 +230,9 @@ const AttributeFilterBlock = ( {
212230 */
213231 const getSelectedTerms = useCallback (
214232 ( newChecked ) => {
233+ if ( ! Array . isArray ( attributeTerms ) ) {
234+ return [ ] ;
235+ }
215236 return attributeTerms . reduce ( ( acc , term ) => {
216237 if ( newChecked . includes ( term . slug ) ) {
217238 acc . push ( term ) ;
@@ -231,12 +252,15 @@ const AttributeFilterBlock = ( {
231252 const redirectPageForPhpTemplate = useCallback (
232253 ( query , allFiltersRemoved = false ) => {
233254 if ( allFiltersRemoved ) {
255+ if ( ! attributeObject ?. taxonomy ) {
256+ return ;
257+ }
234258 const currentQueryArgKeys = Object . keys (
235259 getQueryArgs ( window . location . href )
236260 ) ;
237261
238262 const parsedTaxonomy = parseTaxonomyToGenerateURL (
239- attributeObject ? .taxonomy
263+ attributeObject . taxonomy
240264 ) ;
241265
242266 const url = currentQueryArgKeys . reduce (
@@ -267,7 +291,7 @@ const AttributeFilterBlock = ( {
267291 [ pageUrl , attributeObject ?. taxonomy ]
268292 ) ;
269293
270- const onSubmit = ( checkedFilters ) => {
294+ const onSubmit = ( checkedFilters : string [ ] ) => {
271295 const query = updateAttributeFilter (
272296 productAttributesQuery ,
273297 setProductAttributesQuery ,
@@ -283,7 +307,7 @@ const AttributeFilterBlock = ( {
283307 } ;
284308
285309 const updateCheckedFilters = useCallback (
286- ( checkedFilters ) => {
310+ ( checkedFilters : string [ ] ) => {
287311 if ( isEditor ) {
288312 return ;
289313 }
@@ -324,6 +348,7 @@ const AttributeFilterBlock = ( {
324348 // Track ATTRIBUTES QUERY changes so the block reflects current filters.
325349 useEffect ( ( ) => {
326350 if (
351+ previousCheckedQuery &&
327352 ! isShallowEqual ( previousCheckedQuery , currentCheckedQuery ) && // checked query changed
328353 ! isShallowEqual ( checked , currentCheckedQuery ) // checked query doesn't match the UI
329354 ) {
@@ -345,15 +370,23 @@ const AttributeFilterBlock = ( {
345370 */
346371 const onChange = useCallback (
347372 ( checkedValue ) => {
348- const getFilterNameFromValue = ( filterValue ) => {
349- const { name } = displayedOptions . find (
373+ const getFilterNameFromValue = ( filterValue : string ) => {
374+ const result = displayedOptions . find (
350375 ( option ) => option . value === filterValue
351376 ) ;
352377
353- return name ;
378+ if ( result ) {
379+ return result . name ;
380+ }
354381 } ;
355382
356- const announceFilterChange = ( { filterAdded, filterRemoved } ) => {
383+ const announceFilterChange = ( {
384+ filterAdded,
385+ filterRemoved,
386+ } : {
387+ filterAdded ?: string | null ;
388+ filterRemoved ?: string | null ;
389+ } ) => {
357390 const filterAddedName = filterAdded
358391 ? getFilterNameFromValue ( filterAdded )
359392 : null ;
@@ -526,7 +559,8 @@ const AttributeFilterBlock = ( {
526559 return null ;
527560 }
528561
529- const TagName = `h${ blockAttributes . headingLevel } ` ;
562+ const TagName =
563+ `h${ blockAttributes . headingLevel } ` as keyof JSX . IntrinsicElements ;
530564 const isLoading = ! blockAttributes . isPreview && attributeTermsLoading ;
531565 const isDisabled = ! blockAttributes . isPreview && filteredCountsLoading ;
532566
0 commit comments