From e9e14f331f93a3b8210567a5310c68bcbebea77d Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Wed, 25 Sep 2024 14:40:24 +0200 Subject: [PATCH] Clean up SearchRouterList item types --- .../Search/SearchRouter/SearchRouterList.tsx | 24 +++++++++++-------- src/components/Search/types.ts | 6 ----- .../Search/SingleIconListItem.tsx | 11 ++++----- src/components/SelectionList/types.ts | 15 ++++++++++++ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchRouterList.tsx b/src/components/Search/SearchRouter/SearchRouterList.tsx index b8a01a92d349..f40585163edf 100644 --- a/src/components/Search/SearchRouter/SearchRouterList.tsx +++ b/src/components/Search/SearchRouter/SearchRouterList.tsx @@ -1,10 +1,10 @@ import React, {useCallback} from 'react'; import * as Expensicons from '@components/Icon/Expensicons'; -import type {SearchQueryJSON, SearchRouterListItem} from '@components/Search/types'; +import type {SearchQueryJSON} from '@components/Search/types'; import SelectionList from '@components/SelectionList'; import SingleIconListItem from '@components/SelectionList/Search/SingleIconListItem'; -import type {ListItemWithSingleIcon, SingleIconListItemProps} from '@components/SelectionList/Search/SingleIconListItem'; -import type {SectionListDataType, UserListItemProps} from '@components/SelectionList/types'; +import type {SingleIconListItemProps} from '@components/SelectionList/Search/SingleIconListItem'; +import type {SectionListDataType, SingleIconListItemType, UserListItemProps, UserListItemType} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -29,25 +29,28 @@ type SearchRouterListProps = { closeAndClearRouter: () => void; }; -function SearchRouterItem(props: UserListItemProps | SingleIconListItemProps) { +function SearchRouterItem(props: UserListItemProps | SingleIconListItemProps) { const styles = useThemeStyles(); - if (props.item.itemType === CONST.SEARCH.ROUTER_LIST_ITEM_TYPE.REPORT) { + // Here instead of checking itemType prepare correct type guards for the prop types and use them + if (props.item) { + // this cast would actually happen in the type guard; type guard can stay in this file I think + const actuallyProps = props as UserListItemProps; return ( )} + {...actuallyProps} /> ); } // eslint-disable-next-line react/jsx-props-no-spreading - return )} />; + return ; } function SearchRouterList({currentQuery, reportForContextualSearch, recentSearches, recentReports, onSearchSubmit, updateUserSearchQuery, closeAndClearRouter}: SearchRouterListProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const sections: Array> = []; + const sections: Array> = []; if (currentQuery?.inputQuery) { sections.push({ @@ -95,8 +98,9 @@ function SearchRouterList({currentQuery, reportForContextualSearch, recentSearch sections.push({title: translate('search.recentChats'), data: recentReportsData}); const onSelectRow = useCallback( - (item: SearchRouterListItem) => { + (item: SingleIconListItemType | UserListItemType) => { // eslint-disable-next-line default-case + // Here instead of switch on itemType prepare correct type guards for the types of list item: SingleIconListItemType and UserListItemType and use them here switch (item.itemType) { case CONST.SEARCH.ROUTER_LIST_ITEM_TYPE.SEARCH: // Handle selection of "Recent search" @@ -126,7 +130,7 @@ function SearchRouterList({currentQuery, reportForContextualSearch, recentSearch ); return ( - + sections={sections} onSelectRow={onSelectRow} ListItem={SearchRouterItem} diff --git a/src/components/Search/types.ts b/src/components/Search/types.ts index 360d8e8fe902..195073f8b89f 100644 --- a/src/components/Search/types.ts +++ b/src/components/Search/types.ts @@ -1,9 +1,6 @@ import type {ValueOf} from 'react-native-gesture-handler/lib/typescript/typeUtils'; -import type {ListItemWithSingleIcon} from '@components/SelectionList/Search/SingleIconListItem'; -import type {OptionData} from '@libs/ReportUtils'; import type CONST from '@src/CONST'; import type {SearchDataTypes} from '@src/types/onyx/SearchResults'; -import type {ItemWithQuery} from './SearchRouter/SearchRouterList'; /** Model of the selected transaction */ type SelectedTransactionInfo = { @@ -76,8 +73,6 @@ type SearchQueryJSON = { flatFilters: QueryFilters; } & SearchQueryAST; -type SearchRouterListItem = (OptionData | (ListItemWithSingleIcon & ItemWithQuery)) & {itemType?: ValueOf}; - export type { SelectedTransactionInfo, SelectedTransactions, @@ -96,5 +91,4 @@ export type { InvoiceSearchStatus, TripSearchStatus, ChatSearchStatus, - SearchRouterListItem, }; diff --git a/src/components/SelectionList/Search/SingleIconListItem.tsx b/src/components/SelectionList/Search/SingleIconListItem.tsx index 9aa3274d3686..8d85a9a5f3f1 100644 --- a/src/components/SelectionList/Search/SingleIconListItem.tsx +++ b/src/components/SelectionList/Search/SingleIconListItem.tsx @@ -2,15 +2,12 @@ import React from 'react'; import {View} from 'react-native'; import Icon from '@components/Icon'; import BaseListItem from '@components/SelectionList/BaseListItem'; -import type {ListItem} from '@components/SelectionList/types'; +import type {ListItem, SingleIconListItemType} from '@components/SelectionList/types'; import TextWithTooltip from '@components/TextWithTooltip'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import type IconAsset from '@src/types/utils/IconAsset'; -type ListItemWithSingleIcon = {singleIcon?: IconAsset} & ListItem; - -type SingleIconListItemProps = { +type SingleIconListItemProps = { item: TItem; isFocused?: boolean; showTooltip?: boolean; @@ -18,7 +15,7 @@ type SingleIconListItemProps = { onFocus?: () => void; }; -function SingleIconListItem({item, isFocused, showTooltip, onSelectRow, onFocus}: SingleIconListItemProps) { +function SingleIconListItem({item, isFocused, showTooltip, onSelectRow, onFocus}: SingleIconListItemProps) { const styles = useThemeStyles(); const theme = useTheme(); @@ -71,4 +68,4 @@ function SingleIconListItem({item, isFocus SingleIconListItem.displayName = 'SingleIconListItem'; export default SingleIconListItem; -export type {ListItemWithSingleIcon, SingleIconListItemProps}; +export type {SingleIconListItemProps}; diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 8c8c33eb2cc9..85621ac02654 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -1,6 +1,7 @@ import type {MutableRefObject, ReactElement, ReactNode} from 'react'; import type {GestureResponderEvent, InputModeOptions, LayoutChangeEvent, SectionListData, StyleProp, TextInput, TextStyle, ViewStyle} from 'react-native'; import type {SearchRouterItem} from '@components/Search/SearchRouter/SearchRouterList'; +import type {SearchQueryString} from '@components/Search/types'; import type {BrickRoad} from '@libs/WorkspacesSettingsUtils'; // eslint-disable-next-line no-restricted-imports import type CursorStyles from '@styles/utils/cursor/types'; @@ -241,6 +242,18 @@ type ReportListItemType = ListItem & transactions: TransactionListItemType[]; }; +type UserListItemType = ListItem & { + foo: string; +}; + +// In general I don't think we can create a generic `SingleIconListItemType` if you want to store query in it +// Im afraid we might just name it properly like SomethingSomethingSearchItem... +type SingleIconListItemType = ListItem & { + singleIcon?: IconAsset; + query: SearchQueryString; + itemType: string; // fix this +}; + type ListItemProps = CommonListItemProps & { /** The section list item */ item: TItem; @@ -600,6 +613,8 @@ export type { TransactionListItemProps, TransactionListItemType, UserListItemProps, + UserListItemType, + SingleIconListItemType, ValidListItem, ReportActionListItemType, ChatListItemProps,