Skip to content
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

fix(types): improve useDataQuery types #1347

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open

fix(types): improve useDataQuery types #1347

wants to merge 21 commits into from

Conversation

Birkbjo
Copy link
Member

@Birkbjo Birkbjo commented Apr 17, 2023

Key features

  1. Add types for the QueryResult based on the Query. So the query-keys are typed on the data object when not passing in a generic type to useDataQuery.
  2. Changes QueryResult to be any instead of JsonMap, due to problems with JsonMap. Please refer to this comment for more context.
  3. Adds improved type to engine.query, so it follows the same types as useDataQuery.
  4. Added an alias for the return type of useDataQuery, because when I first worked with this I was very confused by the QueryRenderInput-name of the result of useDataQuery.
  5. Adds Pager type and some related utility types to make it easy to create a Result-type that is paged.

Description

Builds on @eirikhaugstulen improvement of adding a generic type for useDataQuery.


Checklist

  • Have written Documentation
    • If not needed, explain why, otherwise remove this bullet point
  • Has tests coverage
    • Only types are changed, so no runtime changes. But I did change some tests to be typed, so it's easier to check that the types work as they should

Screenshots

image
Type-completion on query-keys when not passing in a generic type

@Birkbjo Birkbjo changed the title Improve useDataQuery default types Improve useDataQuery types Apr 20, 2023
@@ -40,19 +40,22 @@ export interface ExecuteHookResult<ReturnType> {
data?: ReturnType
}

export interface QueryState {
export interface QueryState<TQueryResult> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer to rename this to QueryResultData

@kabaros kabaros changed the base branch from master to eh/fix/AddGenericTypesToUseDataQuery April 20, 2023 16:11
@kabaros kabaros requested review from a team and eirikhaugstulen April 20, 2023 16:12
@Mohammer5
Copy link
Contributor

Could you add some docs with examples?
Although possible, it's takes some time to wrap your head around what a type argument would/should look like.

@Birkbjo Birkbjo changed the title Improve useDataQuery types fix(types): improve useDataQuery types Apr 24, 2023
@Birkbjo Birkbjo requested a review from amcgee April 24, 2023 12:34
@kabaros kabaros force-pushed the eh/fix/AddGenericTypesToUseDataQuery branch from fbcbaa9 to f8bb081 Compare May 1, 2023 10:40
Base automatically changed from eh/fix/AddGenericTypesToUseDataQuery to master May 2, 2023 08:54
@@ -19,7 +18,11 @@ export interface ResolvedResourceQuery extends ResourceQuery {
}

export type Query = Record<string, ResourceQuery>
export type QueryResult = JsonMap
export type QueryResult = any
Copy link
Member Author

@Birkbjo Birkbjo May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could potentially use unknown here instead, but then we are enforcing consumers to type their data. Which could be a breaking change. But because JsonMap-type don't really work anyway (and you had to do the same thing as in screenshot below), I'm all for using unknown if we want to enforce typing the result. any could be "easier" to use, but of course then you lose the types...

If we used unknown you would have to do something like this (which you have to do now anyway with JsonMap:

image

Comment on lines 243 to 250
// keep previous data, so list does not disappear when refetching/fetching new page
const prevData = React.useRef(data)
const stableData = data || prevData.current
React.useEffect(() => {
if(data) {
prevData.current = data
}
}, [data])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't really sure if I should include this in the example. I do think we should either add an option to useQuery for react-query's keepPreviousData. Or preferably just have an reactQueryOptions that we can pass directly... But I do understand the argument if we want to keep the APIs separate, to not rely on react-query if we were to replace it...

However I do think an example like this would be bad without the functionality of "keeping" old data when using pagination - especially since all lists would flicker/be hidden regardless of what "pager" updated, because data will be undefined when fetching... And since it's out of scope for this PR to have an option like that, I opted to include this pretty simple workaround in the example. And we can remove it/update it we decide to implement an option for this.

@Birkbjo Birkbjo requested a review from ismay May 5, 2023 22:09
@Birkbjo Birkbjo requested review from kabaros and tomzemp May 5, 2023 22:14
@nnkogift
Copy link

Hello @Birkbjo

I have improvement suggestions if you're still working on this pull request. I think the generic type passed on the useDataQuery hook can be passed down to its refetch function so that its return value can also be typed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants