Skip to content

Commit

Permalink
feat: support discriminating null and undefined within useFragment
Browse files Browse the repository at this point in the history
  • Loading branch information
n1ru4l committed Jun 13, 2024
1 parent 99f449c commit 95e94b2
Show file tree
Hide file tree
Showing 27 changed files with 271 additions and 10 deletions.
19 changes: 19 additions & 0 deletions .changeset/fresh-files-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@graphql-codegen/client-preset': minor
---

Support discriminating `null` and `undefined` within the `useFragment` function.

```ts
function MyComponent(props: FragmentType<typeof MyFragment> | null) {
const data = useFragment(MyFragment, props)
// data is `MyFragment | null`
}

function MyComponent(props: FragmentType<typeof MyFragment> | undefined) {
const data = useFragment(MyFragment, props)
// data is `MyFragment | undefined`
}
```

Before, the returned type from `useFragment` was always `TType | null | undefined`.
10 changes: 10 additions & 0 deletions dev-test/gql-tag-operations-masking/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
12 changes: 6 additions & 6 deletions dev-test/gql-tag-operations-masking/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react';
import { gql, FragmentType, useFragment } from '../gql';
import { graphql, FragmentType, useFragment } from '../gql';
import { useQuery } from 'urql';

const TweetFragment = gql(/* GraphQL */ `
const TweetFragment = graphql(/* GraphQL */ `
fragment TweetFragment on Tweet {
id
body
...TweetAuthorFragment
}
`);

const TweetAuthorFragment = gql(/* GraphQL */ `
const TweetAuthorFragment = graphql(/* GraphQL */ `
fragment TweetAuthorFragment on Tweet {
id
author {
Expand All @@ -21,7 +21,7 @@ const TweetAuthorFragment = gql(/* GraphQL */ `
}
`);

const TweetsFragment = gql(/* GraphQL */ `
const TweetsFragment = graphql(/* GraphQL */ `
fragment TweetsFragment on Query {
Tweets {
id
Expand All @@ -30,7 +30,7 @@ const TweetsFragment = gql(/* GraphQL */ `
}
`);

const TweetAppQuery = gql(/* GraphQL */ `
const TweetAppQuery = graphql(/* GraphQL */ `
query TweetAppQuery {
...TweetsFragment
}
Expand All @@ -53,7 +53,7 @@ const TweetAuthor = (props: { tweet: FragmentType<typeof TweetAuthorFragment> })
return <div>{tweet.author?.username}</div>;
};

const Tweets = (props: { tweets: FragmentType<typeof TweetsFragment> | undefined }) => {
const Tweets = (props: { tweets: FragmentType<typeof TweetsFragment> | null | undefined }) => {
const tweets = useFragment(TweetsFragment, props.tweets);

return <ul>{tweets?.Tweets?.map(tweet => <Tweet key={tweet.id} tweet={tweet} />) ?? null}</ul>;
Expand Down
10 changes: 10 additions & 0 deletions dev-test/gql-tag-operations-urql/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions dev-test/gql-tag-operations/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions dev-test/gql-tag-operations/graphql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
8 changes: 4 additions & 4 deletions dev-test/gql-tag-operations/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

import { gql, DocumentType } from '../gql.js';
import { graphql, DocumentType } from '../gql/gql.js';

const FooQuery = gql(/* GraphQL */ `
const FooQuery = graphql(/* GraphQL */ `
query Foo {
Tweets {
id
}
}
`);

const LelFragment = gql(/* GraphQL */ `
const LelFragment = graphql(/* GraphQL */ `
fragment Lel on Tweet {
id
body
}
`);

const BarQuery = gql(/* GraphQL */ `
const BarQuery = graphql(/* GraphQL */ `
query Bar {
Tweets {
...Lel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/persisted-documents/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/apollo-client-defer/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/apollo-client/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/http-executor/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/nextjs-swr/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/tanstack-react-query/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/react/urql/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/typescript-esm/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/typescript-graphql-request/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
10 changes: 10 additions & 0 deletions examples/vite/vite-react-cts/src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
): TType | undefined;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
): TType | null;
// return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
Expand Down
Loading

0 comments on commit 95e94b2

Please sign in to comment.