-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
narrow return value of useFragment
based on returnPartialData
option
#10760
Conversation
🦋 Changeset detectedLatest commit: c0266b7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! LGTM ✅
I also like the idea of introducing some utility types to make writing this kind of test easier (e.g. https://github.com/total-typescript/ts-reset/blob/main/src/tests/utils.ts), but since we don't have anything like that yet, @ts-expect-error
comments do the trick :)
Edit: just noticed the useFragment
tests will need some updates with this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad to see this works, but it's tempting to fully remove the returnPartialData
option from useFragment
, and let result.complete
and result.missing
indicate whether the result.data
is partial or complete.
What do you think about that simplification? If we eliminate returnPartialData
, that might solve the second bullet point from #10650 as well…
Edit: same comment as @Alessia about fixing those useFragment
tests
Yeah, tests on the branch seemed generally broken, so I had not given much thought to CI results. I can try to fix that tomorrow - and move this over to 3.7. As for removing the Essentially we have to choose between these two: const result = useFragment({
fragment: typedNode,
from: { __typename: "Query" },
returnPartialData: false,
});
if (result.data) {
// ...
} and const result = useFragment({
fragment: typedNode,
from: { __typename: "Query" },
});
if (result.complete) {
// ...
} I would argue that once So further down the line we would have one of these two scenarios: function doSomeThing(data: TData | undefined) {
if (!data) return;
// data is TData now
} and function doSomeThing(data: Partial<TData> | undefined) {
// we have no way of knowing here if `TData` is complete
} I would personally prefer the first option here. |
@phryneas if we use a discriminated union as such: // this isn't the complete type, but it illustrates the point
type UseFragmentResult<TData> =
| { complete: true, data: TData } // note `data` is not `undefined` in this case
| { complete: false, data: Partial<TData> | undefined } Wouldn't you still be able to achieve the same type of thing with function doSomeThing(data: TData) {
// only accept `TData
}
if (result.complete) {
// result.data is now `TData` according to the discriminated union
doSomeThing(result.data)
} I personally like to keep the surface area of the API as small as possible, so one less option is attractive to me, especially if the return value captures whether the data is partial or complete. |
Yes, but I had to do the Of course the whole thing could be simulated in userland by doing something like const result = useFragment({
fragment: typedNode,
from: { __typename: "Query" },
});
const data = result.complete ? result.data : undefined So it would not be the end of the world, just a bit less convenient 🤔. So either way, I probably don't have a very strong opinion here :) |
My $0.02: I see the merits in both approaches (there can be an ergonomic advantage to |
This would address the first point raised over in #10650
Checklist: