T
TanStack13mo ago
adverse-sapphire

Typing response based on request params

Hi! I'm trying to figure out if there's a way to type the response based on request param in a way that will make it easy later for TS to figure out the correct response type. What I have so far is:
type Os = 'android' | 'ios'

type RequestPayload = {
os: Os
...
}

type Response<T extends Os> = {
data:
T extends 'android'
? AndroidData :
T extends 'ios'
? IOSData :
never
}
}

export const fetch = async <T extends RequestPayload>((payload: T) => {
const url = ...
const response = await http<Response<T['os']>(url, body)
return response.data
})
type Os = 'android' | 'ios'

type RequestPayload = {
os: Os
...
}

type Response<T extends Os> = {
data:
T extends 'android'
? AndroidData :
T extends 'ios'
? IOSData :
never
}
}

export const fetch = async <T extends RequestPayload>((payload: T) => {
const url = ...
const response = await http<Response<T['os']>(url, body)
return response.data
})
Now, this is a slightly simplified version and it works, but I'm wondering what's the easiest way to later narrow the actual response type based on the actual os value. If I do something like:
const { data } = useQuery({
queryKey: [payload],
queryFn: () => fetch(payload)
})

if (payload.os === 'android') {
// I'd expect data to be typed here as Response<'android'>, but it's Response<'android' | 'ios'>
}
const { data } = useQuery({
queryKey: [payload],
queryFn: () => fetch(payload)
})

if (payload.os === 'android') {
// I'd expect data to be typed here as Response<'android'>, but it's Response<'android' | 'ios'>
}
Is it possible? Should it "just" work? Is there some way to make it work without casting data manually using data as Response<'android'>?
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?