algolia / react-instantsearch

⚡️ Lightning-fast search for React and React Native applications, by Algolia.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/
MIT License
1.97k stars 386 forks source link

Guide on making custom components with Typescript #3007

Closed danawoodman closed 1 year ago

danawoodman commented 3 years ago

Is your feature request related to a problem? Please describe 🙏

First off, thanks for a great product!

In a way yes, it is really hard to use this library with Typescript. The custom connectors don't seem to allow you to use React in a proper way by passing down props from a connected component and there is no simple way to get Typescript to work well with "connected" components.

For example, I'm trying to pass down a prop to my connectHits wrapped component but TS barfs because I have no way of passing in additional props to a wrapped component (at least as far as I can tell). I'd like the Algolia library/TS support to work in a "Reacty" way by allowing me to pass down additional props if I need to. Right now I'm at a bit of a standstill on how to do this.

Describe the solution you'd like 🤔

I'd like a guide on how to use this library with Typescript including examples of how to do that with all the connect type utilities. Not sure if this will require changes to the types as well.

Describe alternatives you've considered ✨

Use //@ts-ignore?

Additional context

image

image

image

Haroenv commented 3 years ago

Today this is handled by the community in @types/react-instantsearch-core, and I see it's not so consistent, however it's correct for connectHits. Here's how to do it correctly (although you need to extend the hits props for some reason instead of mixing):

import {
  connectHits,
  Hits,
  InstantSearch,
  SearchBox,
} from 'react-instantsearch-dom';
import { Hit } from 'react-instantsearch-core';
import algoliasearch from 'algoliasearch/lite';

const searchClient = algoliasearch('latency', '123');

const CustomHits = connectHits<{ hits: Hit<{}>[]; someProp: string }, {}>(
  ({ hits, someProp }) => {
    return (
      <>
        {someProp}
        {hits.map(() => (
          <>hi</>
        ))}
      </>
    );
  }
);

export default function App() {
  return (
    <InstantSearch searchClient={searchClient} indexName="123">
      hi
      <SearchBox />
      <Hits />
      <CustomHits someProp="val" />
    </InstantSearch>
  );
}

Unfortunately this isn't fixable unless a breaking change of the types is done, for which I'm not sure what the process is

sarahdayan commented 1 year ago

@danawoodman Did @Haroenv's reply help you out?

Today we strongly recommend migrating to React InstantSearch Hooks, which is written in TypeScript and will soon fully replace React InstantSearch v6. You can find the upgrade guide here.

I'm closing this ticket since there's no activity, feel free to reopen if needed.