lucaong / react-minisearch

React integration for the MiniSearch client side full-text search library
MIT License
48 stars 8 forks source link

React-Minisearch: Argument of type 'IUserDisplayInfo[]' is not assignable to parameter of type 'readonly never[]'. #41

Closed Jens-Mikael closed 10 months ago

Jens-Mikael commented 10 months ago

Explain the bug

I am trying to fetch data from firestore using the firebase sdk and useQuery from Tanstack-Query, but when I try to index it to react-minisearch it throws a type error (the error is down below).

I am completely new to tsc and I'm trying to migrate my js react app into tsc.

Code

The useQuery hook that fetches data from getPublicData and indexes it to react-minisearch:

  const { data: setsData } = useQuery<ILibraryCard[]>({
    queryKey: ["publicSets"],
    queryFn: async () => {
      const data: ILibraryCard[] = await getPublicSets();
      await addAllAsync(data);
      return data;
    },
    refetchOnWindowFocus: false,
  });

data in addAllSync throws error

Argument of type 'IUserDisplayInfo[]' is not assignable to parameter of type 'readonly never[]'. Type 'IUserDisplayInfo' is not assignable to type 'never'.ts(2345)

My getPublicData hook:

export const getPublicSets = async (): Promise<ILibraryCard[]> => {
  const docsQuery = query(
    collection(firestore, "studySets"),
    where("isPublic", "==", true)
  );
  const arr: ILibraryCard[] = [];
  const docsSnap = await getDocs(docsQuery);
  docsSnap.forEach((doc) => {
    const data = doc.data();
    arr.push({
      title: data.head.title,
      description: data.head.description,
      id: doc.id,
      creator: data.creator,
    });
  });
  return arr;
};

Interface:


export interface ILibraryCard {
  title: string;
  description: string;
  id: string;
  creator: string;
}

Any help would be much appreciated :)

If this issue is missing something critical related to the issue, please let me know so that I can provide any additional information since this is my very first issue that I've made.

lucaong commented 10 months ago

Hi @Jens-Mikael , at first glance, this does not seem like a bug in react-minisearch, but rather a typing problem in the application code. The error message is Argument of type 'IUserDisplayInfo[]' is not assignable to parameter of type 'readonly never[]'. Type 'IUserDisplayInfo' is not assignable to type 'never'.ts(2345), indicating that a value of type IUserDisplayInfo[] is being passed to a function that expects a parameter of type never[]. The never type in TypeScript occurs in a few situations, for example it is the return type of a function that never returns (e.g. because it always throws an error or because of an infinite loop), or it is used explicitly in order to prevent assigning/passing any value. The code you pasted does not show where the never types occurs.

If the error is due to the type of the addAllAsync first argument, here is one guess: maybe the generic type T of useMiniSearch<T> ends up being never for some reason (not sure why, as I don't see the part of the code calling useMiniSearch). I say this, because the type of the first argument of addAllAsync is readonly T[], so if T was never then addAllAsync would expect an argument of type never[], like in your error. What happens if you explicitly provide the type T, by calling useMiniSearch as useMiniSearch<ILibraryCard>?

Consider though that the error mentions that the provided value has type IUserDisplayInfo, not ILibraryCard, and I do not know from your code the relation between these two types, if any.

I hope this helps. If not, you could try to paste here some more code, in particular:

Jens-Mikael commented 10 months ago

Thank you @lucaong, I got the issue fixed and it was exactly, how you said, caused by the useMiniSearch hook that you explained, because I hadn't provided it the types of objects it will include

  const {
    autoSuggest,
    suggestions,
    addAllAsync,
    addAll,
    search,
    searchResults,
    isIndexing,
  } = useMiniSearch<ILibraryCard | IUserDisplayInfo>([], miniSearchOptions);

Some code clarifying what is the type IUserDisplayInfo, and how it relates to ILibraryCard[]

And also, sorry for providing too little information, since I also had a similar hook that indexed IUserDisplayInfo and because of the similarity of those hooks, i felt it was unnecessary to include it in the Issue post.

  const { data: everyUserData } = useQuery<IUserDisplayInfo[]>({
    queryKey: ["everyUser"],
    queryFn: async () => {
      const data: IUserDisplayInfo[] = await getEveryUser();
      await addAllAsync(data);
      return data;
    },
    refetchOnWindowFocus: false,
  });
lucaong commented 10 months ago

Thanks for the response @Jens-Mikael , and happy my answer helped you in spotting the issue :)