T
TanStack3y ago
extended-yellow

select propType in Typescript?

kindly can u guide whats the type of this select prop ? its showing any
No description
No description
13 Replies
extended-yellow
extended-yellowOP3y ago
@TkDodo 🔮
crude-lavender
crude-lavender3y ago
The example is in JS
extended-yellow
extended-yellowOP3y ago
yes m asking what's the typescript version of this kindly can u guide lit bit m new to typescript
crude-lavender
crude-lavender3y ago
It needs a generic
extended-yellow
extended-yellowOP3y ago
i did like this now having error on query
No description
extended-yellow
extended-yellowOP3y ago
No description
multiple-amethyst
multiple-amethyst3y ago
You need to tell useQuery the return type of select
const usePost = <T>(select: (data: ITodo[]) => T) => useQuery<ITodo[], Error, T>({
select,
...
})
const usePost = <T>(select: (data: ITodo[]) => T) => useQuery<ITodo[], Error, T>({
select,
...
})
(edited just in case someone looks at this example) (I'm assuming that your .get(getAllPosts) promise chain returns an ITodo[]) In this example, we're not constraining T (the return type of select) because it could be anything, but based on your business logic, you can constrain (extends) it if needed we're just using T to pass it to useQuery so it can cast the data returned to "whatever is returned by select" Also, the error on queryKey is kinda confusing, but that is what comes up when you have an error typing the select. Sometimes with typescript, you have to compromise the readability of your errors for the flexibility and exhaustivity of your generics...
extended-yellow
extended-yellowOP3y ago
@bostonsheraff https://codesandbox.io/s/react-typescript-forked-yxggll can u check here how we can fix its still showing same error
multiple-amethyst
multiple-amethyst3y ago
Yep you are right, I was certain I had done it just like I told you in the past (not even that distant of a past) but now I'm questioning everything I think I had it backwards: useQuery<IPost[], Error, T> but the explanation still applies. Sorry for the confusion!
extended-yellow
extended-yellowOP3y ago
yes now its workin tysm for help! 😍
extended-yellow
extended-yellowOP3y ago
@bostonsheraff i have one little question now its working what if i want this dynamically is it possible ? later on i will use same component to all query so m think to chnage name usePost to somehing relavant
No description
multiple-amethyst
multiple-amethyst3y ago
For what you are asking, you can just pass in 2 generics instead of a single one: <T, U>(select: (data: T) => U) => ... However, I would tend to advise against that because you're (maybe) going to be stuck trying to make everything too flexible and generic My advice would be to look into having maybe an "argument constructor":
const { data } = useQuery(getQueryArgs('posts'))
const { data } = useQuery(getQueryArgs('posts'))
Which can then easily be overridden for every specific use-case
const { data } = useQuery({
...getQueryArgs('posts'),
select: (data) => { /*...*/ },
})
const { data } = useQuery({
...getQueryArgs('posts'),
select: (data) => { /*...*/ },
})
If getQueryArgs works for you, you can abstract it even more and define a "global queryFn" where you instantiate the query client
const client = new QueryClient({
defaultOptions: {
queries: {
queryFn: ({queryKey}) => {
/* here your axios call, determined based on the queryKey */
}
}
}
})
const client = new QueryClient({
defaultOptions: {
queries: {
queryFn: ({queryKey}) => {
/* here your axios call, determined based on the queryKey */
}
}
}
})
And then it makes your queries very simple:
const {data} = useQuery({queryKey: ['posts']})
const {data} = useQuery({queryKey: ['posts']})
However I've never tried this approach, so I'm not sure how the typing goes for this
frail-apricot
frail-apricot3y ago
Depending on how many different "select" options you would actually pass to the hook, it may be simpler to not accept a "select" param but to create multiple hooks instead. Like, if in reality you only have 2 different callers for usePost and they expect different fields, you could just create usePostForX and usePostForY: both would have 0 arguments and do the select internally. That way you would just rely on inference.

Did you find this page helpful?