From 861639d284098bbd737f1aa73c364c4be47e04f6 Mon Sep 17 00:00:00 2001 From: alessia Date: Thu, 18 May 2023 14:09:38 -0400 Subject: [PATCH 1/5] chore: improve type signature of useBackgroundQuery refetch --- src/react/hooks/__tests__/useBackgroundQuery.test.tsx | 6 ++---- src/react/hooks/useBackgroundQuery.ts | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index 8f841823cf9..bac52940cab 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -38,7 +38,7 @@ import { useBackgroundQuery, useReadQuery } from '../useBackgroundQuery'; import { ApolloProvider } from '../../context'; import { SuspenseCache } from '../../cache'; import { InMemoryCache } from '../../../cache'; -import { FetchMoreFunction } from '../../../react'; +import { FetchMoreFunction, RefetchFunction } from '../../../react'; import { QueryReference } from '../../cache/QueryReference'; function renderIntegrationTest({ @@ -1875,9 +1875,7 @@ describe('useBackgroundQuery', () => { queryRef, refetch, }: { - refetch: ( - variables?: Partial | undefined - ) => Promise>; + refetch: RefetchFunction; queryRef: QueryReference; onChange: (id: string) => void; }) { diff --git a/src/react/hooks/useBackgroundQuery.ts b/src/react/hooks/useBackgroundQuery.ts index db43c4a1c13..881199b1464 100644 --- a/src/react/hooks/useBackgroundQuery.ts +++ b/src/react/hooks/useBackgroundQuery.ts @@ -6,10 +6,7 @@ import type { } from '../../core'; import { useApolloClient } from './useApolloClient'; import type { QueryReference } from '../cache/QueryReference'; -import type { - SuspenseQueryHookOptions, - ObservableQueryFields, -} from '../types/types'; +import type { SuspenseQueryHookOptions } from '../types/types'; import { __use } from './internal'; import { useSuspenseCache } from './useSuspenseCache'; import { @@ -28,7 +25,7 @@ export type UseBackgroundQueryResult< QueryReference, { fetchMore: FetchMoreFunction; - refetch: ObservableQueryFields['refetch']; + refetch: RefetchFunction; } ]; From 243aa179c6272023c5193aa6091e105556324adb Mon Sep 17 00:00:00 2001 From: alessia Date: Mon, 5 Jun 2023 16:46:38 -0400 Subject: [PATCH 2/5] chore: improve useBackgroundQuery/useReadQuery types and type tests --- .../__tests__/useBackgroundQuery.test.tsx | 355 +++++++++++++++--- .../hooks/__tests__/useSuspenseQuery.test.tsx | 58 +-- src/react/hooks/useBackgroundQuery.ts | 84 ++++- src/react/hooks/useSuspenseQuery.ts | 2 - src/react/types/types.ts | 4 + 5 files changed, 427 insertions(+), 76 deletions(-) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index bac52940cab..ccb361498b1 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -9,6 +9,7 @@ import { } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ErrorBoundary, ErrorBoundaryProps } from 'react-error-boundary'; +import { expectTypeOf } from 'expect-type'; import { GraphQLError } from 'graphql'; import { gql, @@ -38,8 +39,11 @@ import { useBackgroundQuery, useReadQuery } from '../useBackgroundQuery'; import { ApolloProvider } from '../../context'; import { SuspenseCache } from '../../cache'; import { InMemoryCache } from '../../../cache'; -import { FetchMoreFunction, RefetchFunction } from '../../../react'; -import { QueryReference } from '../../cache/QueryReference'; +import { + FetchMoreFunction, + RefetchFunction, + QueryReference, +} from '../../../react'; function renderIntegrationTest({ client, @@ -131,6 +135,37 @@ function renderIntegrationTest({ return { ...rest, query, client: _client, renders }; } +interface VariablesCaseData { + character: { + id: string; + name: string; + }; +} + +interface VariablesCaseVariables { + id: string; +} + +function useVariablesIntegrationTestCase() { + const query: TypedDocumentNode< + VariablesCaseData, + VariablesCaseVariables + > = gql` + query CharacterQuery($id: ID!) { + character(id: $id) { + id + name + } + } + `; + const CHARACTERS = ['Spider-Man', 'Black Widow', 'Iron Man', 'Hulk']; + let mocks = [...CHARACTERS].map((name, index) => ({ + request: { query, variables: { id: String(index + 1) } }, + result: { data: { character: { id: String(index + 1), name } } }, + })); + return { mocks, query }; +} + function renderVariablesIntegrationTest({ variables, mocks, @@ -150,32 +185,8 @@ function renderVariablesIntegrationTest({ variables: { id: string }; errorPolicy?: ErrorPolicy; }) { - const CHARACTERS = ['Spider-Man', 'Black Widow', 'Iron Man', 'Hulk']; - - interface QueryData { - character: { - id: string; - name: string; - }; - } + let { mocks: _mocks, query } = useVariablesIntegrationTestCase(); - interface QueryVariables { - id: string; - } - - const query: TypedDocumentNode = gql` - query CharacterQuery($id: ID!) { - character(id: $id) { - id - name - } - } - `; - - let _mocks = [...CHARACTERS].map((name, index) => ({ - request: { query, variables: { id: String(index + 1) } }, - result: { data: { character: { id: String(index + 1), name } } }, - })); // duplicate mocks with (updated) in the name for refetches _mocks = [..._mocks, ..._mocks, ..._mocks].map( ({ request, result }, index) => { @@ -208,7 +219,7 @@ function renderVariablesIntegrationTest({ suspenseCount: number; count: number; frames: { - data: QueryData; + data: VariablesCaseData; networkStatus: NetworkStatus; error: ApolloError | undefined; }[]; @@ -239,11 +250,11 @@ function renderVariablesIntegrationTest({ variables: _variables, queryRef, }: { - variables: QueryVariables; + variables: VariablesCaseVariables; refetch: ( variables?: Partial | undefined - ) => Promise>; - queryRef: QueryReference; + ) => Promise>; + queryRef: QueryReference; }) { const { data, error, networkStatus } = useReadQuery(queryRef); const [variables, setVariables] = React.useState(_variables); @@ -276,7 +287,7 @@ function renderVariablesIntegrationTest({ variables, errorPolicy = 'none', }: { - variables: QueryVariables; + variables: VariablesCaseVariables; errorPolicy?: ErrorPolicy; }) { const [queryRef, { refetch }] = useBackgroundQuery(query, { @@ -294,7 +305,7 @@ function renderVariablesIntegrationTest({ variables, errorPolicy, }: { - variables: QueryVariables; + variables: VariablesCaseVariables; errorPolicy?: ErrorPolicy; }) { return ( @@ -314,7 +325,7 @@ function renderVariablesIntegrationTest({ const { ...rest } = render( ); - const rerender = ({ variables }: { variables: QueryVariables }) => { + const rerender = ({ variables }: { variables: VariablesCaseVariables }) => { return rest.rerender(); }; return { ...rest, query, rerender, client, renders }; @@ -1243,7 +1254,15 @@ describe('useBackgroundQuery', () => { }); it('does not suspend deferred queries with data in the cache and using a "cache-and-network" fetch policy', async () => { - const query = gql` + interface Data { + greeting: { + __typename: string; + message: string; + recipient: { name: string; __typename: string }; + }; + } + + const query: TypedDocumentNode = gql` query { greeting { message @@ -1256,13 +1275,6 @@ describe('useBackgroundQuery', () => { } `; - interface Data { - greeting: { - message: string; - recipient: { name: string }; - }; - } - const link = new MockSubscriptionLink(); const cache = new InMemoryCache(); cache.writeQuery({ @@ -2197,11 +2209,270 @@ describe('useBackgroundQuery', () => { // @ts-expect-error should not allow returnPartialData in options useBackgroundQuery(query, { returnPartialData: true }); }); + it('disallows refetchWritePolicy in BackgroundQueryHookOptions', () => { const { query } = renderIntegrationTest(); // @ts-expect-error should not allow refetchWritePolicy in options useBackgroundQuery(query, { refetchWritePolicy: 'overwrite' }); }); + + it('returns unknown when TData cannot be inferred', () => { + const query = gql` + query { + hello + } + `; + + const [queryRef] = useBackgroundQuery(query); + const { data } = useReadQuery(queryRef); + + expectTypeOf(data).toEqualTypeOf(); + }); + + it('disallows wider variables type than specified', () => { + const { query } = useVariablesIntegrationTestCase(); + + // @ts-expect-error should not allow wider TVariables type + useBackgroundQuery(query, { variables: { id: '1', foo: 'bar' } }); + }); + + it('returns TData in default case', () => { + const { query } = useVariablesIntegrationTestCase(); + + const [inferredQueryRef] = useBackgroundQuery(query); + const { data: inferred } = useReadQuery(inferredQueryRef); + + expectTypeOf(inferred).toEqualTypeOf(); + expectTypeOf(inferred).not.toEqualTypeOf(); + + const [explicitQueryRef] = useBackgroundQuery< + VariablesCaseData, + VariablesCaseVariables + >(query); + + const { data: explicit } = useReadQuery(explicitQueryRef); + + expectTypeOf(explicit).toEqualTypeOf(); + expectTypeOf(explicit).not.toEqualTypeOf(); + }); + + it('returns TData | undefined with errorPolicy: "ignore"', () => { + const { query } = useVariablesIntegrationTestCase(); + + const [inferredQueryRef] = useBackgroundQuery(query, { + errorPolicy: 'ignore', + }); + const { data: inferred } = useReadQuery(inferredQueryRef); + + expectTypeOf(inferred).toEqualTypeOf(); + expectTypeOf(inferred).not.toEqualTypeOf(); + + const [explicitQueryRef] = useBackgroundQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { + errorPolicy: 'ignore', + }); + + const { data: explicit } = useReadQuery(explicitQueryRef); + + expectTypeOf(explicit).toEqualTypeOf(); + expectTypeOf(explicit).not.toEqualTypeOf(); + }); + + it('returns TData | undefined with errorPolicy: "all"', () => { + const { query } = useVariablesIntegrationTestCase(); + + const [inferredQueryRef] = useBackgroundQuery(query, { + errorPolicy: 'all', + }); + const { data: inferred } = useReadQuery(inferredQueryRef); + + expectTypeOf(inferred).toEqualTypeOf(); + expectTypeOf(inferred).not.toEqualTypeOf(); + + const [explicitQueryRef] = useBackgroundQuery(query, { + errorPolicy: 'all', + }); + const { data: explicit } = useReadQuery(explicitQueryRef); + + expectTypeOf(explicit).toEqualTypeOf(); + expectTypeOf(explicit).not.toEqualTypeOf(); + }); + + it('returns TData with errorPolicy: "none"', () => { + const { query } = useVariablesIntegrationTestCase(); + + const [inferredQueryRef] = useBackgroundQuery(query, { + errorPolicy: 'none', + }); + const { data: inferred } = useReadQuery(inferredQueryRef); + + expectTypeOf(inferred).toEqualTypeOf(); + expectTypeOf(inferred).not.toEqualTypeOf(); + + const [explicitQueryRef] = useBackgroundQuery(query, { + errorPolicy: 'none', + }); + const { data: explicit } = useReadQuery(explicitQueryRef); + + expectTypeOf(explicit).toEqualTypeOf(); + expectTypeOf(explicit).not.toEqualTypeOf(); + }); + + // it('returns DeepPartial with returnPartialData: true', () => { + // const { query } = useVariablesQueryCase(); + + // const { data: inferred } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // returnPartialData: true, + // }); + + // expectTypeOf(inferred).toEqualTypeOf>(); + // expectTypeOf(inferred).not.toEqualTypeOf(); + + // const { data: explicit } = useSuspenseQuery(query, { + // returnPartialData: true, + // }); + + // expectTypeOf(explicit).toEqualTypeOf>(); + // expectTypeOf(explicit).not.toEqualTypeOf(); + // }); + + // it('returns TData with returnPartialData: false', () => { + // const { query } = useVariablesQueryCase(); + + // const { data: inferred } = useSuspenseQuery(query, { + // returnPartialData: false, + // }); + + // expectTypeOf(inferred).toEqualTypeOf(); + // expectTypeOf(inferred).not.toEqualTypeOf< + // DeepPartial + // >(); + + // const { data: explicit } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // returnPartialData: false, + // }); + + // expectTypeOf(explicit).toEqualTypeOf(); + // expectTypeOf(explicit).not.toEqualTypeOf< + // DeepPartial + // >(); + // }); + + // it('returns TData when passing an option that does not affect TData', () => { + // const { query } = useVariablesQueryCase(); + + // const { data: inferred } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // fetchPolicy: 'no-cache', + // }); + + // expectTypeOf(inferred).toEqualTypeOf(); + // expectTypeOf(inferred).not.toEqualTypeOf< + // DeepPartial + // >(); + + // const { data: explicit } = useSuspenseQuery(query, { + // fetchPolicy: 'no-cache', + // }); + + // expectTypeOf(explicit).toEqualTypeOf(); + // expectTypeOf(explicit).not.toEqualTypeOf< + // DeepPartial + // >(); + // }); + + // it('handles combinations of options', () => { + // const { query } = useVariablesQueryCase(); + + // const { data: inferredPartialDataIgnore } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // returnPartialData: true, + // errorPolicy: 'ignore', + // }); + + // expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< + // DeepPartial | undefined + // >(); + // expectTypeOf( + // inferredPartialDataIgnore + // ).not.toEqualTypeOf(); + + // const { data: explicitPartialDataIgnore } = useSuspenseQuery(query, { + // returnPartialData: true, + // errorPolicy: 'ignore', + // }); + + // expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< + // DeepPartial | undefined + // >(); + // expectTypeOf( + // explicitPartialDataIgnore + // ).not.toEqualTypeOf(); + + // const { data: inferredPartialDataNone } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // returnPartialData: true, + // errorPolicy: 'none', + // }); + + // expectTypeOf(inferredPartialDataNone).toEqualTypeOf< + // DeepPartial + // >(); + // expectTypeOf( + // inferredPartialDataNone + // ).not.toEqualTypeOf(); + + // const { data: explicitPartialDataNone } = useSuspenseQuery(query, { + // returnPartialData: true, + // errorPolicy: 'none', + // }); + + // expectTypeOf(explicitPartialDataNone).toEqualTypeOf< + // DeepPartial + // >(); + // expectTypeOf( + // explicitPartialDataNone + // ).not.toEqualTypeOf(); + // }); + + // it('returns correct TData type when combined options that do not affect TData', () => { + // const { query } = useVariablesQueryCase(); + + // const { data: inferred } = useSuspenseQuery(query, { + // fetchPolicy: 'no-cache', + // returnPartialData: true, + // errorPolicy: 'none', + // }); + + // expectTypeOf(inferred).toEqualTypeOf>(); + // expectTypeOf(inferred).not.toEqualTypeOf(); + + // const { data: explicit } = useSuspenseQuery< + // VariablesCaseData, + // VariablesCaseVariables + // >(query, { + // fetchPolicy: 'no-cache', + // returnPartialData: true, + // errorPolicy: 'none', + // }); + + // expectTypeOf(explicit).toEqualTypeOf>(); + // expectTypeOf(explicit).not.toEqualTypeOf(); + // }); }); }); diff --git a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx index 404f313b0c6..3c5af6afdb2 100644 --- a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx +++ b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx @@ -6928,17 +6928,17 @@ describe('useSuspenseQuery', () => { it('returns TData | undefined with errorPolicy: "all"', () => { const { query } = useVariablesQueryCase(); - const { data: inferred } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: inferred } = useSuspenseQuery(query, { errorPolicy: 'all', }); expectTypeOf(inferred).toEqualTypeOf(); expectTypeOf(inferred).not.toEqualTypeOf(); - const { data: explicit } = useSuspenseQuery(query, { + const { data: explicit } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { errorPolicy: 'all', }); @@ -6949,17 +6949,17 @@ describe('useSuspenseQuery', () => { it('returns TData with errorPolicy: "none"', () => { const { query } = useVariablesQueryCase(); - const { data: inferred } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: inferred } = useSuspenseQuery(query, { errorPolicy: 'none', }); expectTypeOf(inferred).toEqualTypeOf(); expectTypeOf(inferred).not.toEqualTypeOf(); - const { data: explicit } = useSuspenseQuery(query, { + const { data: explicit } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { errorPolicy: 'none', }); @@ -6970,17 +6970,17 @@ describe('useSuspenseQuery', () => { it('returns DeepPartial with returnPartialData: true', () => { const { query } = useVariablesQueryCase(); - const { data: inferred } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: inferred } = useSuspenseQuery(query, { returnPartialData: true, }); expectTypeOf(inferred).toEqualTypeOf>(); expectTypeOf(inferred).not.toEqualTypeOf(); - const { data: explicit } = useSuspenseQuery(query, { + const { data: explicit } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { returnPartialData: true, }); @@ -7016,10 +7016,7 @@ describe('useSuspenseQuery', () => { it('returns TData when passing an option that does not affect TData', () => { const { query } = useVariablesQueryCase(); - const { data: inferred } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: inferred } = useSuspenseQuery(query, { fetchPolicy: 'no-cache', }); @@ -7028,7 +7025,10 @@ describe('useSuspenseQuery', () => { DeepPartial >(); - const { data: explicit } = useSuspenseQuery(query, { + const { data: explicit } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { fetchPolicy: 'no-cache', }); @@ -7041,31 +7041,31 @@ describe('useSuspenseQuery', () => { it('handles combinations of options', () => { const { query } = useVariablesQueryCase(); - const { data: inferredPartialDataIgnore } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: explicitPartialDataIgnore } = useSuspenseQuery(query, { returnPartialData: true, errorPolicy: 'ignore', }); - expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< + expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< DeepPartial | undefined >(); expectTypeOf( - inferredPartialDataIgnore + explicitPartialDataIgnore ).not.toEqualTypeOf(); - const { data: explicitPartialDataIgnore } = useSuspenseQuery(query, { + const { data: inferredPartialDataIgnore } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { returnPartialData: true, errorPolicy: 'ignore', }); - expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< + expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< DeepPartial | undefined >(); expectTypeOf( - explicitPartialDataIgnore + inferredPartialDataIgnore ).not.toEqualTypeOf(); const { data: inferredPartialDataNone } = useSuspenseQuery< diff --git a/src/react/hooks/useBackgroundQuery.ts b/src/react/hooks/useBackgroundQuery.ts index 881199b1464..2979863a9f8 100644 --- a/src/react/hooks/useBackgroundQuery.ts +++ b/src/react/hooks/useBackgroundQuery.ts @@ -6,7 +6,7 @@ import type { } from '../../core'; import { useApolloClient } from './useApolloClient'; import type { QueryReference } from '../cache/QueryReference'; -import type { SuspenseQueryHookOptions } from '../types/types'; +import type { SuspenseQueryHookOptions, NoInfer } from '../types/types'; import { __use } from './internal'; import { useSuspenseCache } from './useSuspenseCache'; import { @@ -16,10 +16,11 @@ import { } from './useSuspenseQuery'; import type { FetchMoreFunction, RefetchFunction } from './useSuspenseQuery'; import { canonicalStringify } from '../../cache'; +import type { DeepPartial } from '../../utilities'; import { invariant } from '../../utilities/globals'; export type UseBackgroundQueryResult< - TData = any, + TData = unknown, TVariables extends OperationVariables = OperationVariables > = [ QueryReference, @@ -30,7 +31,84 @@ export type UseBackgroundQueryResult< ]; export function useBackgroundQuery< - TData = any, + TData, + TVariables extends OperationVariables, + TOptions extends Omit< + SuspenseQueryHookOptions, + 'variables' | 'returnPartialData' | 'refetchWritePolicy' + > +>( + query: DocumentNode | TypedDocumentNode, + options?: Omit< + SuspenseQueryHookOptions, NoInfer>, + 'returnPartialData' | 'refetchWritePolicy' + > & + TOptions +): UseBackgroundQueryResult< + TOptions['errorPolicy'] extends 'ignore' | 'all' + ? // TOptions['returnPartialData'] extends true + // ? DeepPartial | undefined + // : TData | undefined + TData | undefined + : // : TOptions['returnPartialData'] extends true + // ? DeepPartial + TData, + TVariables +>; + +export function useBackgroundQuery< + TData = unknown, + TVariables extends OperationVariables = OperationVariables +>( + query: DocumentNode | TypedDocumentNode, + options: Omit< + SuspenseQueryHookOptions, NoInfer>, + 'returnPartialData' | 'refetchWritePolicy' + > & { + returnPartialData: true; + errorPolicy: 'ignore' | 'all'; + } +): UseBackgroundQueryResult | undefined, TVariables>; + +export function useBackgroundQuery< + TData = unknown, + TVariables extends OperationVariables = OperationVariables +>( + query: DocumentNode | TypedDocumentNode, + options: Omit< + SuspenseQueryHookOptions, NoInfer>, + 'returnPartialData' | 'refetchWritePolicy' + > & { + errorPolicy: 'ignore' | 'all'; + } +): UseBackgroundQueryResult; + +// export function useBackgroundQuery< +// TData = unknown, +// TVariables extends OperationVariables = OperationVariables +// >( +// query: DocumentNode | TypedDocumentNode, +// options: Omit< +// SuspenseQueryHookOptions, NoInfer>, +// 'returnPartialData' | 'refetchWritePolicy' +// > & { +// returnPartialData: true; +// } +// ): UseBackgroundQueryResult, TVariables>; + +export function useBackgroundQuery< + TData = unknown, + TVariables extends OperationVariables = OperationVariables +>( + query: DocumentNode | TypedDocumentNode, + options?: Omit< + SuspenseQueryHookOptions, NoInfer>, + 'returnPartialData' | 'refetchWritePolicy' + > +): UseBackgroundQueryResult; + +export function useBackgroundQuery< + TData = unknown, TVariables extends OperationVariables = OperationVariables >( query: DocumentNode | TypedDocumentNode, diff --git a/src/react/hooks/useSuspenseQuery.ts b/src/react/hooks/useSuspenseQuery.ts index e381e590102..58144811c83 100644 --- a/src/react/hooks/useSuspenseQuery.ts +++ b/src/react/hooks/useSuspenseQuery.ts @@ -61,8 +61,6 @@ export type SubscribeToMoreFunction< TVariables extends OperationVariables > = ObservableQueryFields['subscribeToMore']; -export type Version = 'main' | 'network'; - export function useSuspenseQuery< TData, TVariables extends OperationVariables, diff --git a/src/react/types/types.ts b/src/react/types/types.ts index 64d0a6b9b7d..863cf27552b 100644 --- a/src/react/types/types.ts +++ b/src/react/types/types.ts @@ -20,6 +20,10 @@ import type { } from '../../core'; import type { SuspenseCache } from '../cache'; +/* QueryReference type */ + +export type { QueryReference } from '../cache/QueryReference'; + /* Common types */ export type { DefaultContext as Context } from "../../core"; From c29a5a40c104b65a692cddf293ba76e86897b864 Mon Sep 17 00:00:00 2001 From: alessia Date: Mon, 5 Jun 2023 16:54:58 -0400 Subject: [PATCH 3/5] chore: update code comments --- .../__tests__/useBackgroundQuery.test.tsx | 144 +----------------- src/react/hooks/useBackgroundQuery.ts | 7 +- 2 files changed, 11 insertions(+), 140 deletions(-) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index ccb361498b1..a2a29a9db69 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -2321,158 +2321,24 @@ describe('useBackgroundQuery', () => { expectTypeOf(explicit).not.toEqualTypeOf(); }); + // TODO: https://github.com/apollographql/apollo-client/issues/10893 // it('returns DeepPartial with returnPartialData: true', () => { - // const { query } = useVariablesQueryCase(); - - // const { data: inferred } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // returnPartialData: true, - // }); - - // expectTypeOf(inferred).toEqualTypeOf>(); - // expectTypeOf(inferred).not.toEqualTypeOf(); - - // const { data: explicit } = useSuspenseQuery(query, { - // returnPartialData: true, - // }); - - // expectTypeOf(explicit).toEqualTypeOf>(); - // expectTypeOf(explicit).not.toEqualTypeOf(); // }); + // TODO: https://github.com/apollographql/apollo-client/issues/10893 // it('returns TData with returnPartialData: false', () => { - // const { query } = useVariablesQueryCase(); - - // const { data: inferred } = useSuspenseQuery(query, { - // returnPartialData: false, - // }); - - // expectTypeOf(inferred).toEqualTypeOf(); - // expectTypeOf(inferred).not.toEqualTypeOf< - // DeepPartial - // >(); - - // const { data: explicit } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // returnPartialData: false, - // }); - - // expectTypeOf(explicit).toEqualTypeOf(); - // expectTypeOf(explicit).not.toEqualTypeOf< - // DeepPartial - // >(); // }); + // TODO: https://github.com/apollographql/apollo-client/issues/10893 // it('returns TData when passing an option that does not affect TData', () => { - // const { query } = useVariablesQueryCase(); - - // const { data: inferred } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // fetchPolicy: 'no-cache', - // }); - - // expectTypeOf(inferred).toEqualTypeOf(); - // expectTypeOf(inferred).not.toEqualTypeOf< - // DeepPartial - // >(); - - // const { data: explicit } = useSuspenseQuery(query, { - // fetchPolicy: 'no-cache', - // }); - - // expectTypeOf(explicit).toEqualTypeOf(); - // expectTypeOf(explicit).not.toEqualTypeOf< - // DeepPartial - // >(); // }); + // TODO: https://github.com/apollographql/apollo-client/issues/10893 // it('handles combinations of options', () => { - // const { query } = useVariablesQueryCase(); - - // const { data: inferredPartialDataIgnore } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // returnPartialData: true, - // errorPolicy: 'ignore', - // }); - - // expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< - // DeepPartial | undefined - // >(); - // expectTypeOf( - // inferredPartialDataIgnore - // ).not.toEqualTypeOf(); - - // const { data: explicitPartialDataIgnore } = useSuspenseQuery(query, { - // returnPartialData: true, - // errorPolicy: 'ignore', - // }); - - // expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< - // DeepPartial | undefined - // >(); - // expectTypeOf( - // explicitPartialDataIgnore - // ).not.toEqualTypeOf(); - - // const { data: inferredPartialDataNone } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // returnPartialData: true, - // errorPolicy: 'none', - // }); - - // expectTypeOf(inferredPartialDataNone).toEqualTypeOf< - // DeepPartial - // >(); - // expectTypeOf( - // inferredPartialDataNone - // ).not.toEqualTypeOf(); - - // const { data: explicitPartialDataNone } = useSuspenseQuery(query, { - // returnPartialData: true, - // errorPolicy: 'none', - // }); - - // expectTypeOf(explicitPartialDataNone).toEqualTypeOf< - // DeepPartial - // >(); - // expectTypeOf( - // explicitPartialDataNone - // ).not.toEqualTypeOf(); // }); + // TODO: https://github.com/apollographql/apollo-client/issues/10893 // it('returns correct TData type when combined options that do not affect TData', () => { - // const { query } = useVariablesQueryCase(); - - // const { data: inferred } = useSuspenseQuery(query, { - // fetchPolicy: 'no-cache', - // returnPartialData: true, - // errorPolicy: 'none', - // }); - - // expectTypeOf(inferred).toEqualTypeOf>(); - // expectTypeOf(inferred).not.toEqualTypeOf(); - - // const { data: explicit } = useSuspenseQuery< - // VariablesCaseData, - // VariablesCaseVariables - // >(query, { - // fetchPolicy: 'no-cache', - // returnPartialData: true, - // errorPolicy: 'none', - // }); - - // expectTypeOf(explicit).toEqualTypeOf>(); - // expectTypeOf(explicit).not.toEqualTypeOf(); // }); }); }); diff --git a/src/react/hooks/useBackgroundQuery.ts b/src/react/hooks/useBackgroundQuery.ts index 2979863a9f8..79e91cf93be 100644 --- a/src/react/hooks/useBackgroundQuery.ts +++ b/src/react/hooks/useBackgroundQuery.ts @@ -46,7 +46,9 @@ export function useBackgroundQuery< TOptions ): UseBackgroundQueryResult< TOptions['errorPolicy'] extends 'ignore' | 'all' - ? // TOptions['returnPartialData'] extends true + ? // TODO: support `returnPartialData` | `refetchWritePolicy` + // see https://github.com/apollographql/apollo-client/issues/10893 + // TOptions['returnPartialData'] extends true // ? DeepPartial | undefined // : TData | undefined TData | undefined @@ -83,6 +85,9 @@ export function useBackgroundQuery< } ): UseBackgroundQueryResult; +// TODO: support `returnPartialData` | `refetchWritePolicy` +// see https://github.com/apollographql/apollo-client/issues/10893 + // export function useBackgroundQuery< // TData = unknown, // TVariables extends OperationVariables = OperationVariables From 0e0e7e1b0b7c0af0ddaa2afc5182cbf8759cee0e Mon Sep 17 00:00:00 2001 From: alessia Date: Mon, 5 Jun 2023 16:55:30 -0400 Subject: [PATCH 4/5] chore: add changeset --- .changeset/friendly-mugs-repeat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/friendly-mugs-repeat.md diff --git a/.changeset/friendly-mugs-repeat.md b/.changeset/friendly-mugs-repeat.md new file mode 100644 index 00000000000..a4050061576 --- /dev/null +++ b/.changeset/friendly-mugs-repeat.md @@ -0,0 +1,5 @@ +--- +'@apollo/client': patch +--- + +Improve `useBackgroundQuery` type interface From 35550c4946cbc206332b70b8bf2440e7e236b2db Mon Sep 17 00:00:00 2001 From: alessia Date: Mon, 5 Jun 2023 17:02:32 -0400 Subject: [PATCH 5/5] chore: fix explicit/inferred references in uSQ test --- .../hooks/__tests__/useSuspenseQuery.test.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx index 3c5af6afdb2..e278cfeaf47 100644 --- a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx +++ b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx @@ -7041,19 +7041,19 @@ describe('useSuspenseQuery', () => { it('handles combinations of options', () => { const { query } = useVariablesQueryCase(); - const { data: explicitPartialDataIgnore } = useSuspenseQuery(query, { + const { data: inferredPartialDataIgnore } = useSuspenseQuery(query, { returnPartialData: true, errorPolicy: 'ignore', }); - expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< + expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< DeepPartial | undefined >(); expectTypeOf( - explicitPartialDataIgnore + inferredPartialDataIgnore ).not.toEqualTypeOf(); - const { data: inferredPartialDataIgnore } = useSuspenseQuery< + const { data: explicitPartialDataIgnore } = useSuspenseQuery< VariablesCaseData, VariablesCaseVariables >(query, { @@ -7061,17 +7061,14 @@ describe('useSuspenseQuery', () => { errorPolicy: 'ignore', }); - expectTypeOf(inferredPartialDataIgnore).toEqualTypeOf< + expectTypeOf(explicitPartialDataIgnore).toEqualTypeOf< DeepPartial | undefined >(); expectTypeOf( - inferredPartialDataIgnore + explicitPartialDataIgnore ).not.toEqualTypeOf(); - const { data: inferredPartialDataNone } = useSuspenseQuery< - VariablesCaseData, - VariablesCaseVariables - >(query, { + const { data: inferredPartialDataNone } = useSuspenseQuery(query, { returnPartialData: true, errorPolicy: 'none', }); @@ -7083,7 +7080,10 @@ describe('useSuspenseQuery', () => { inferredPartialDataNone ).not.toEqualTypeOf(); - const { data: explicitPartialDataNone } = useSuspenseQuery(query, { + const { data: explicitPartialDataNone } = useSuspenseQuery< + VariablesCaseData, + VariablesCaseVariables + >(query, { returnPartialData: true, errorPolicy: 'none', });