Skip to content

Commit 3e2c8de

Browse files
authored
Fix/required variables in query hook (#620)
* fix(react-apollo): variables to be required in query hook when some variable is required * chore(react-apollo): improve test cases * chore(react-apollo): test to check when required string should not be present * chore(react-apollo): generate examples * chore(react-apollo): take skip into account * chore(react-apollo): add changeset
1 parent 15f9d39 commit 3e2c8de

11 files changed

Lines changed: 128 additions & 23 deletions

File tree

.changeset/plenty-ads-destroy.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@graphql-codegen/typescript-react-apollo': minor
3+
---
4+
5+
Improved type-safety: when a query contains required variables, passing the variables object to the
6+
useQuery hook is enforced

dev-test/githunt/types.reactApollo.customSuffix.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ export function useOnCommentAddedSubscription(
423423
baseOptions: Apollo.SubscriptionHookOptions<
424424
OnCommentAddedSubscriptionMyOperation,
425425
OnCommentAddedSubscriptionVariables
426-
>,
426+
> &
427+
({ variables: OnCommentAddedSubscriptionVariables; skip?: boolean } | { skip: boolean }),
427428
) {
428429
const options = { ...defaultOptions, ...baseOptions };
429430
return Apollo.useSubscription<
@@ -484,7 +485,8 @@ export const CommentDocument = gql`
484485
* });
485486
*/
486487
export function useCommentQuery(
487-
baseOptions: Apollo.QueryHookOptions<CommentQueryMyOperation, CommentQueryVariables>,
488+
baseOptions: Apollo.QueryHookOptions<CommentQueryMyOperation, CommentQueryVariables> &
489+
({ variables: CommentQueryVariables; skip?: boolean } | { skip: boolean }),
488490
) {
489491
const options = { ...defaultOptions, ...baseOptions };
490492
return Apollo.useQuery<CommentQueryMyOperation, CommentQueryVariables>(CommentDocument, options);
@@ -613,7 +615,8 @@ export const FeedDocument = gql`
613615
* });
614616
*/
615617
export function useFeedQuery(
616-
baseOptions: Apollo.QueryHookOptions<FeedQueryMyOperation, FeedQueryVariables>,
618+
baseOptions: Apollo.QueryHookOptions<FeedQueryMyOperation, FeedQueryVariables> &
619+
({ variables: FeedQueryVariables; skip?: boolean } | { skip: boolean }),
617620
) {
618621
const options = { ...defaultOptions, ...baseOptions };
619622
return Apollo.useQuery<FeedQueryMyOperation, FeedQueryVariables>(FeedDocument, options);

dev-test/githunt/types.reactApollo.hooks.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,8 @@ export function useOnCommentAddedSubscription(
469469
baseOptions: Apollo.SubscriptionHookOptions<
470470
OnCommentAddedSubscription,
471471
OnCommentAddedSubscriptionVariables
472-
>,
472+
> &
473+
({ variables: OnCommentAddedSubscriptionVariables; skip?: boolean } | { skip: boolean }),
473474
) {
474475
const options = { ...defaultOptions, ...baseOptions };
475476
return Apollo.useSubscription<OnCommentAddedSubscription, OnCommentAddedSubscriptionVariables>(
@@ -530,7 +531,8 @@ export const CommentDocument = gql`
530531
* });
531532
*/
532533
export function useCommentQuery(
533-
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables>,
534+
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables> &
535+
({ variables: CommentQueryVariables; skip?: boolean } | { skip: boolean }),
534536
) {
535537
const options = { ...defaultOptions, ...baseOptions };
536538
return Apollo.useQuery<CommentQuery, CommentQueryVariables>(CommentDocument, options);
@@ -652,7 +654,10 @@ export const FeedDocument = gql`
652654
* },
653655
* });
654656
*/
655-
export function useFeedQuery(baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables>) {
657+
export function useFeedQuery(
658+
baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables> &
659+
({ variables: FeedQueryVariables; skip?: boolean } | { skip: boolean }),
660+
) {
656661
const options = { ...defaultOptions, ...baseOptions };
657662
return Apollo.useQuery<FeedQuery, FeedQueryVariables>(FeedDocument, options);
658663
}

dev-test/githunt/types.reactApollo.preResolveTypes.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ export function useOnCommentAddedSubscription(
423423
baseOptions: Apollo.SubscriptionHookOptions<
424424
OnCommentAddedSubscription,
425425
OnCommentAddedSubscriptionVariables
426-
>,
426+
> &
427+
({ variables: OnCommentAddedSubscriptionVariables; skip?: boolean } | { skip: boolean }),
427428
) {
428429
const options = { ...defaultOptions, ...baseOptions };
429430
return Apollo.useSubscription<OnCommentAddedSubscription, OnCommentAddedSubscriptionVariables>(
@@ -484,7 +485,8 @@ export const CommentDocument = gql`
484485
* });
485486
*/
486487
export function useCommentQuery(
487-
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables>,
488+
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables> &
489+
({ variables: CommentQueryVariables; skip?: boolean } | { skip: boolean }),
488490
) {
489491
const options = { ...defaultOptions, ...baseOptions };
490492
return Apollo.useQuery<CommentQuery, CommentQueryVariables>(CommentDocument, options);
@@ -606,7 +608,10 @@ export const FeedDocument = gql`
606608
* },
607609
* });
608610
*/
609-
export function useFeedQuery(baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables>) {
611+
export function useFeedQuery(
612+
baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables> &
613+
({ variables: FeedQueryVariables; skip?: boolean } | { skip: boolean }),
614+
) {
610615
const options = { ...defaultOptions, ...baseOptions };
611616
return Apollo.useQuery<FeedQuery, FeedQueryVariables>(FeedDocument, options);
612617
}

dev-test/githunt/types.reactApollo.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ export function useOnCommentAddedSubscription(
423423
baseOptions: Apollo.SubscriptionHookOptions<
424424
OnCommentAddedSubscription,
425425
OnCommentAddedSubscriptionVariables
426-
>,
426+
> &
427+
({ variables: OnCommentAddedSubscriptionVariables; skip?: boolean } | { skip: boolean }),
427428
) {
428429
const options = { ...defaultOptions, ...baseOptions };
429430
return Apollo.useSubscription<OnCommentAddedSubscription, OnCommentAddedSubscriptionVariables>(
@@ -484,7 +485,8 @@ export const CommentDocument = gql`
484485
* });
485486
*/
486487
export function useCommentQuery(
487-
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables>,
488+
baseOptions: Apollo.QueryHookOptions<CommentQuery, CommentQueryVariables> &
489+
({ variables: CommentQueryVariables; skip?: boolean } | { skip: boolean }),
488490
) {
489491
const options = { ...defaultOptions, ...baseOptions };
490492
return Apollo.useQuery<CommentQuery, CommentQueryVariables>(CommentDocument, options);
@@ -606,7 +608,10 @@ export const FeedDocument = gql`
606608
* },
607609
* });
608610
*/
609-
export function useFeedQuery(baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables>) {
611+
export function useFeedQuery(
612+
baseOptions: Apollo.QueryHookOptions<FeedQuery, FeedQueryVariables> &
613+
({ variables: FeedQueryVariables; skip?: boolean } | { skip: boolean }),
614+
) {
610615
const options = { ...defaultOptions, ...baseOptions };
611616
return Apollo.useQuery<FeedQuery, FeedQueryVariables>(FeedDocument, options);
612617
}

dev-test/githunt/types.reactApollo.v2.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,8 @@ export function useOnCommentAddedSubscription(
424424
baseOptions: ApolloReactHooks.SubscriptionHookOptions<
425425
OnCommentAddedSubscription,
426426
OnCommentAddedSubscriptionVariables
427-
>,
427+
> &
428+
({ variables: OnCommentAddedSubscriptionVariables; skip?: boolean } | { skip: boolean }),
428429
) {
429430
const options = { ...defaultOptions, ...baseOptions };
430431
return ApolloReactHooks.useSubscription<
@@ -485,7 +486,8 @@ export const CommentDocument = gql`
485486
* });
486487
*/
487488
export function useCommentQuery(
488-
baseOptions: ApolloReactHooks.QueryHookOptions<CommentQuery, CommentQueryVariables>,
489+
baseOptions: ApolloReactHooks.QueryHookOptions<CommentQuery, CommentQueryVariables> &
490+
({ variables: CommentQueryVariables; skip?: boolean } | { skip: boolean }),
489491
) {
490492
const options = { ...defaultOptions, ...baseOptions };
491493
return ApolloReactHooks.useQuery<CommentQuery, CommentQueryVariables>(CommentDocument, options);
@@ -614,7 +616,8 @@ export const FeedDocument = gql`
614616
* });
615617
*/
616618
export function useFeedQuery(
617-
baseOptions: ApolloReactHooks.QueryHookOptions<FeedQuery, FeedQueryVariables>,
619+
baseOptions: ApolloReactHooks.QueryHookOptions<FeedQuery, FeedQueryVariables> &
620+
({ variables: FeedQueryVariables; skip?: boolean } | { skip: boolean }),
618621
) {
619622
const options = { ...defaultOptions, ...baseOptions };
620623
return ApolloReactHooks.useQuery<FeedQuery, FeedQueryVariables>(FeedDocument, options);

dev-test/star-wars/__generated__/HeroNameConditional.tsx

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev-test/star-wars/types.refetchFn.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,8 @@ export function useHeroNameConditionalInclusionQuery(
670670
baseOptions: Apollo.QueryHookOptions<
671671
HeroNameConditionalInclusionQuery,
672672
HeroNameConditionalInclusionQueryVariables
673-
>,
673+
> &
674+
({ variables: HeroNameConditionalInclusionQueryVariables; skip?: boolean } | { skip: boolean }),
674675
) {
675676
const options = { ...defaultOptions, ...baseOptions };
676677
return Apollo.useQuery<
@@ -749,7 +750,8 @@ export function useHeroNameConditionalExclusionQuery(
749750
baseOptions: Apollo.QueryHookOptions<
750751
HeroNameConditionalExclusionQuery,
751752
HeroNameConditionalExclusionQueryVariables
752-
>,
753+
> &
754+
({ variables: HeroNameConditionalExclusionQueryVariables; skip?: boolean } | { skip: boolean }),
753755
) {
754756
const options = { ...defaultOptions, ...baseOptions };
755757
return Apollo.useQuery<

dev-test/test-message/types.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ export type EscalateMutation = {
122122
* });
123123
*/
124124
export function useGetMessagesQuery(
125-
baseOptions: Apollo.QueryHookOptions<GetMessagesQuery, GetMessagesQueryVariables>,
125+
baseOptions: Apollo.QueryHookOptions<GetMessagesQuery, GetMessagesQueryVariables> &
126+
({ variables: GetMessagesQueryVariables; skip?: boolean } | { skip: boolean }),
126127
) {
127128
const options = { ...defaultOptions, ...baseOptions };
128129
return Apollo.useQuery<GetMessagesQuery, GetMessagesQueryVariables>(

packages/plugins/typescript/react-apollo/src/visitor.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ export class ReactApolloVisitor extends ClientSideBaseVisitor<
375375
): string {
376376
const nodeName = node.name?.value ?? '';
377377
const suffix = this._getHookSuffix(nodeName, operationType);
378+
const shouldEnforceRequiredVariables = hasRequiredVariables && operationType !== 'Mutation';
378379
const operationName: string =
379380
this.convertName(nodeName, {
380381
suffix,
@@ -385,11 +386,14 @@ export class ReactApolloVisitor extends ClientSideBaseVisitor<
385386
this.imports.add(this.getApolloReactCommonImport(true));
386387
this.imports.add(this.getApolloReactHooksImport(false));
387388
this.imports.add(this.getDefaultOptions());
388-
389389
const hookFns = [
390390
`export function use${operationName}(baseOptions${
391-
hasRequiredVariables && operationType !== 'Mutation' ? '' : '?'
392-
}: ${this.getApolloReactHooksIdentifier()}.${operationType}HookOptions<${operationResultType}, ${operationVariablesTypes}>) {
391+
shouldEnforceRequiredVariables ? '' : '?'
392+
}: ${this.getApolloReactHooksIdentifier()}.${operationType}HookOptions<${operationResultType}, ${operationVariablesTypes}>${
393+
!shouldEnforceRequiredVariables
394+
? ''
395+
: ` & ({ variables: ${operationVariablesTypes}; skip?: boolean; } | { skip: boolean; }) `
396+
}) {
393397
const options = {...defaultOptions, ...baseOptions}
394398
return ${this.getApolloReactHooksIdentifier()}.use${operationType}<${operationResultType}, ${operationVariablesTypes}>(${this.getDocumentNodeVariable(
395399
node,

0 commit comments

Comments
 (0)