Search code examples
reactjstypescriptreact-hookstsx

How to properly use satisfies


I'm building a custom React hook using latest TypeScript. I have issues understanding how to properly use satisfies operator. The reason why I want to use it is because I'm unable to pass conditional values.

My Hook:

import { useQuery } from 'react-query';
import { axiosClient } from '@src/features/@Api';
import type {
  FeathersFind,
  FeathersQuery,
} from '@features/@Api/@types/feathers';
import type { Model } from '@features/@Api/@types/models';

type Result = FeathersFind & {
  data: Model[];
};

type Query = FeathersQuery & Model;

export const useFetchModels = (query?: Query) => {
  const defaultQuery = {
    $limit: 1000,
    $sort: {
      createdAt: -1,
    },
    ...(query || {}),
  };
  const { isFetching, isLoading, refetch, data, ...rest } = useQuery(
    'query-models',
    async () => {
      const { data }: { data: Result } = await axiosClient.get('/models', {
        params: defaultQuery,
      });
      return data;
    },
    {
      cacheTime: 1000 * 60 * 60,
    }
  );
  return { isFetching, isLoading, refetch, data, ...rest };
};

How I use it

  const [selectedMakeId, setSelectedMakeId] = React.useState('imagine-valid-id-here');
  const { data: models } = useFetchModels({
    makeId: selectedMakeId,
  });

The error:

Argument of type '{ makeId: string; }' is not assignable to parameter of type 'Query | undefined'.
 Type '{ makeId: string; }' is missing the following properties from type 'Model': _id, name, make, createdAt, updatedAt

The types: (tried FeathersQuery | Model; and FeathersQuery & Model;)

type Query = FeathersQuery | Model;
export type FeathersQuery = {
  $limit?: number;
  $skip?: number;
  $sort?: {
    [key: string]: 1 | -1;
  };
};
export type Model = {
  _id: string;
  name: string;
  make: Make;
  makeId: string;
  createdAt: Date;
  updatedAt: Date;
};

End goal: I want to conditionally be able to pass ANY of the values from both objects. I'm guessing I need to use new operator satisfied for it?


Solution

  • The code lacks a few types so it's hard to be 100% sure of the intent.

    Assuming the intent is to pass in any field of Model to us it as a filter in the useFetchModels hook, then what you are actually looking for is Partial. This will allow you to specify any property present on Model but will not require you to specify all the required properties of Model (it makes all properties of the passed in type optional)

    type Query = FeathersQuery & Partial<Model>;
    

    Playground Link