diff --git a/packages/web/src/components/withCellHOC.tsx b/packages/web/src/components/withCellHOC.tsx index ca8f3b155656..362c92833ffc 100644 --- a/packages/web/src/components/withCellHOC.tsx +++ b/packages/web/src/components/withCellHOC.tsx @@ -22,18 +22,26 @@ export type CellLoadingEmptyStateComponent = Omit< OperationResult, 'error' | 'loading' | 'data' > -export type CellSuccessStateComponent = - | Omit +export type CellSuccessStateComponent = + | Omit, 'error' | 'loading' | 'data'> | DataObject -export interface WithCellProps { - beforeQuery?: (props: TProps) => { variables: TProps } - QUERY: DocumentNode | ((variables: Record) => DocumentNode) - afterQuery?: (data: DataObject) => DataObject - Loading?: React.FC +export interface WithCellProps< + TData, + TVariables extends Record, + TInitialData = TData, + TProps extends { variables: TVariables } & Record = { + variables: TVariables + }, + TProcessedProps = TProps +> { + beforeQuery?: (props: TProps) => TProcessedProps + QUERY: DocumentNode | ((variables: TProcessedProps) => DocumentNode) + afterQuery?: (data: TInitialData) => TData + Loading?: React.FC Failure?: React.FC Empty?: React.FC - Success: React.FC + Success: React.FC> } /** @@ -89,36 +97,40 @@ const isEmpty = (data: DataObject) => { return isDataNull(data) || isDataEmptyArray(data) } -export const withCell = ({ +export function withCell< + TData = any, + TVariables extends Record = any +>({ beforeQuery = (props) => ({ variables: props, fetchPolicy: 'cache-and-network', nextFetchPolicy: 'cache-first', }), QUERY, - afterQuery = (data) => ({ ...data }), + afterQuery = (data: TData) => data, Loading = () => <>Loading..., Failure, Empty, Success, -}: WithCellProps) => { +}: WithCellProps) { + type TProps = Parameters[0] + // If its prerendering, render the Cell's Loading component if (global.__REDWOOD__PRERENDERING) { - return (props: Record) => + return (props: TProps) => } - return (props: Record) => { - const { - children, // eslint-disable-line @typescript-eslint/no-unused-vars - ...variables - } = props + return (props: TProps) => { + if ('children' in props) { + throw Error( + 'Cells should not have any children, or any props named children.' + ) + } return ( {({ error, loading, data, ...queryRest }) => { if (error) {