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
})


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'>
}

Is it possible? Should it "just" work? Is there some way to make it work without casting
data
manually using data as Response<'android'>?
Was this page helpful?