preactjs / preact-router

:earth_americas: URL router for Preact.
http://npm.im/preact-router
MIT License
1.01k stars 156 forks source link

Can't understand how get typescript work with route params #438

Closed bezenson closed 4 months ago

bezenson commented 1 year ago

I created a router in a way that is explained in the description:

    <Router>
      <Products path={routePath('/:id?')} />
      <Cart path={routePath('/cart')} />
    </Router>

Products component has matches, path, url props inside.

When I am describing them in interface - I am getting error in root tsx file:

Type '{ path: string; }' is not assignable to type 'IntrinsicAttributes & ProductsProps & Readonly<Attributes & { children?: ComponentChildren; ref?: Ref | undefined; }>'. Type '{ path: string; }' is missing the following properties from type 'ProductsProps': matches, url, idts(2322)

interface ProductsProps {
  path: string;
  matches: { id: string; };
  url: string;
  id: string;
}

const Products: FunctionComponent<ProductsProps> = (props) => {
  console.log('Products props', props);

  return <div />
};

Of course I can make props optional, but this is a hack, not a solution. When I render component inside <Route> it will always have this props.

rschristian commented 1 year ago

Of course I can make props optional, but this is a hack, not a solution

Not really, no. This is an inherent limitation of TypeScript and type safety in general. AFAIK, TS offers no mechanism to override or extend the props of child nodes. If you say ProductProps takes specific props, then they need to be supplied or marked as optional.

However, there's sort of a workaround in the Route component, if you want to appease TS:

import { Route, Router } from 'preact-router';

function App() {
    return (
        <Router>
            <Route path={routePath('/:id?')} component={Products} />
            <Route path={routePath('/cart')} component={Cart} />
        </Router>
    );
} 

This will get rid of the error.

bezenson commented 1 year ago

@rschristian It looks like a solution. Thank you. Will be good to add it to README.MD

rschristian commented 1 year ago

PRs welcome

zlondrej commented 4 months ago

@rschristian Here's a PR: https://github.com/preactjs/preact-router/pull/465