Issue Description
With modern hook signatures (TypeOverrides.signatureStyle: "modern"), useQuery incorrectly includes dataState: "partial" (and therefore DeepPartial<TData> for data) when TVariables is a large / complex input object — even if returnPartialData is omitted or set to the literal false.
With a small TVariables type, the same call correctly yields "complete" | "empty" | "streaming" only.
This matches the docs expectation that "partial" / DeepPartial should only appear when returnPartialData is enabled:
https://www.apollographql.com/docs/react/data/typescript#type-narrowing-data-with-datastate
Link to Reproduction
CodeSandbox (node template, @apollo/client@4.2.6): https://codesandbox.io/p/sandbox/fp82hz
Gist: https://gist.github.com/oceandrama/436975fa619df9b807195dcbae4f0894
simpleVars typechecks; complexVars fails with dataState including "partial" despite returnPartialData: false.
Note: TypeScript Playground ATA often fails to acquire @apollo/client types (complex package exports / peers), so prefer CodeSandbox/gist above.
Reproduction Steps
- Enable modern signatures via
TypeOverrides.signatureStyle: "modern".
- Call
useQuery with a TypedDocumentNode whose variables include a large optional input object (many nested optional fields), similar to a real GraphQL INPUT_OBJECT.
- Inspect
dataState (e.g. with satisfies).
- Observe that
"partial" is present even with returnPartialData: false.
- Compare with the same setup using a small variables type —
"partial" is absent.
Suspected cause
In useQuery.ResultForOptions, "partial" is included unless:
OptionWithFallback<TOptions, DefaultOptions, "returnPartialData"> extends false
With complex TVariables, TypeScript appears to fail to keep a narrow inferred TOptions and falls back toward the full useQuery.Options constraint, where returnPartialData?: boolean. Then boolean extends false is false, so "partial" is always added.
Relevant sources (@apollo/client@4.2.6):
react/hooks/useQuery.d.ts — ResultForOptions / modern overload with circular TOptions extends Options & VariablesOption<...>
utilities/internal/types/OptionWithFallback.d.ts
A more default-safe check would be closer to extends true ? "partial" : never (only add "partial" when the option is known to be true). Tradeoff: a dynamic boolean flag would then be typed optimistically.
This is not specific to gql.tada / codegen — the same happens with a hand-written TypedDocumentNode and a large variables type.
@apollo/client version
4.2.6
Issue Description
With modern hook signatures (
TypeOverrides.signatureStyle: "modern"),useQueryincorrectly includesdataState: "partial"(and thereforeDeepPartial<TData>fordata) whenTVariablesis a large / complex input object — even ifreturnPartialDatais omitted or set to the literalfalse.With a small
TVariablestype, the same call correctly yields"complete" | "empty" | "streaming"only.This matches the docs expectation that
"partial"/DeepPartialshould only appear whenreturnPartialDatais enabled:https://www.apollographql.com/docs/react/data/typescript#type-narrowing-data-with-datastate
Link to Reproduction
CodeSandbox (node template,
@apollo/client@4.2.6): https://codesandbox.io/p/sandbox/fp82hzGist: https://gist.github.com/oceandrama/436975fa619df9b807195dcbae4f0894
simpleVarstypechecks;complexVarsfails withdataStateincluding"partial"despitereturnPartialData: false.Note: TypeScript Playground ATA often fails to acquire
@apollo/clienttypes (complex packageexports/ peers), so prefer CodeSandbox/gist above.Reproduction Steps
TypeOverrides.signatureStyle: "modern".useQuerywith aTypedDocumentNodewhose variables include a large optional input object (many nested optional fields), similar to a real GraphQLINPUT_OBJECT.dataState(e.g. withsatisfies)."partial"is present even withreturnPartialData: false."partial"is absent.Suspected cause
In
useQuery.ResultForOptions,"partial"is included unless:With complex
TVariables, TypeScript appears to fail to keep a narrow inferredTOptionsand falls back toward the fulluseQuery.Optionsconstraint, wherereturnPartialData?: boolean. Thenboolean extends falseis false, so"partial"is always added.Relevant sources (
@apollo/client@4.2.6):react/hooks/useQuery.d.ts—ResultForOptions/ modern overload with circularTOptions extends Options & VariablesOption<...>utilities/internal/types/OptionWithFallback.d.tsA more default-safe check would be closer to
extends true ? "partial" : never(only add"partial"when the option is known to betrue). Tradeoff: a dynamicbooleanflag would then be typed optimistically.This is not specific to gql.tada / codegen — the same happens with a hand-written
TypedDocumentNodeand a large variables type.@apollo/clientversion4.2.6