Search code examples
typescriptreact-querymutation

Define type for props in mutation function


I recently working on a react project that has typescript & ReactQuery. Im new to typescript & searched for it but didn't understand how to define types in this situation:

export interface IPropertyAPI {
  useGetProperties: () => {
    mutate: (
      id: string | undefined,
      statusId: string | undefined,
      typeId: string | undefined,
      rooms: string | undefined,
      neighborhood: string | undefined,
      district: string | undefined,
      priceMin: string | undefined,
      priceMax: string | undefined,
      createdAtAfter: string | undefined,
      createdAtBefore: string | undefined,
      ordering: string | undefined,
      onSuccess: any,
      ) => void,
    data: any,
    isLoading: boolean,
  },
  useGetDetails: () => {
    mutate: (id: string | undefined) => void,
    data: any,
  }
}

export const propertyAPI: IPropertyAPI = {
  useGetProperties: () => useMutation(
    'getProperties',
    (
      ordering,
      id,
      statusId,
      typeId,
      rooms,
      neighborhood,
      district,
      priceMin,
      priceMax,
      createdAtAfter,
      createdAtBefore,
    ) => axios
      .get(
        `/estates/?offset=20&ordering=${
          ordering
        }&propertyId${
          id
        }&statusId${
          statusId
        }&typeId${
          typeId
        }&rooms${
          rooms
        }&neighborhood${
          neighborhood
        }&district${
          district
        }&priceMin${
          priceMin
        }&priceMax${
          priceMax
        }&createdAtAfter${
          createdAtAfter
        }&createdAtBefore${
          createdAtBefore
        }`
      ),
    {
      onSuccess: (data) => data,
    }
  )

Error: TS2322: Type 'UseMutationResult<any, unknown, string | undefined, unknown>' is not assignable to type '{ mutate: (id: string | undefined, statusId: string | undefined, typeId: string | undefined, rooms: string | undefined, neighborhood: string | undefined, district: string | undefined, priceMin: string | undefined, priceMax: string | undefined}'.

Could you please tell why i got error for this? or a link to an answer.

Thanks

I tried defining props in that interface but since i dont know much about typescript, i dont know what to do


Solution

  • First, you make a type for the params:

    interface Params {
      ordering?: string,
      id?: string,
      statusId?: string,
      typeId?: string,
      rooms?: string,
      neighborhood?: string,
      district?: string,
      priceMin?: string,
      priceMax?: string,
      createdAtAfter?: string,
      createdAtBefore?: string
    }
    

    Now, you can just use the type that the library exposes as your return value.

    export interface IPropertyAPI {
      useGetProperties:  () => UseMutationResult<Params>
    }
    

    The UseMutationResult type actually take 4 generic arguments. The first one is what the mutationFn returns, and the second is the type of the error the same function will throw. You can look up the rest in the docs.

    Now, in all likelyhood, you probably don't need to give the types explicitly, it should all work automatically through type inference. So you can give the types in the mutationFn, and then use the hook and you should get the types.

    Also, you can pass the params as an object in the second argument to axios.get, so that you don't need to manually create the string:

    axios.get('/estates/', {
      params: {
        ordering: ''
        ...
      }
    })