T
TanStack•2y ago
fascinating-indigo

How do you provide a default select function and keep TypeScript happy?

I'm using v4 and trying to follow this example tweet https://twitter.com/TkDodo/status/1657026702512467970/photo/1 I'd like to provide a default select function, but also give the user the ability to override it.
export type GetBillResponse = {
bill: BillResponseObject
}

export const useBillQuery = <TData = BillResponseObject>(
billId?: number,
select?: (data: GetBillResponse) => TData
) => {
return useQuery({
queryKey: queryKeys.bill(billId),
queryFn: () => getBill(billId),
enabled: !!billId,
select: select ?? ((data) => data.bill),
})
}
export type GetBillResponse = {
bill: BillResponseObject
}

export const useBillQuery = <TData = BillResponseObject>(
billId?: number,
select?: (data: GetBillResponse) => TData
) => {
return useQuery({
queryKey: queryKeys.bill(billId),
queryFn: () => getBill(billId),
enabled: !!billId,
select: select ?? ((data) => data.bill),
})
}
This gives me a TS error saying no overload matches this call, but I think the real issue is that my default select function has the type:
(data: GetBillResponse) => BillResponseObject
(data: GetBillResponse) => BillResponseObject
and that can't be assigned to type:
(data: GetBillResponse) => TData
(data: GetBillResponse) => TData
Is it possible to have a default select function but still allow an override?
Dominik 🔮 (@TkDodo) on X
It doesn't take a lot of #TypeScript magic to get type inference with the select option in React Query. We need: - One generic with a default value - Types for the select argument That's it 🙌
From An unknown user
Twitter
5 Replies
conscious-sapphire
conscious-sapphire•2y ago
show a TS playground please because I'm pretty sure this code should work
conscious-sapphire
conscious-sapphire•2y ago
Oh, you want data.bill if no select is supplied? That doesn't work
fascinating-indigo
fascinating-indigoOP•2y ago
Oh, you want data.bill if no select is supplied? That doesn't work
Yeah I was hoping to build a default select into the query itself No worries if it doesn't work, I was curious if it was possible, but it's easy enough to pass in a select

Did you find this page helpful?