OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Typescript not reporting on missing HOC props from component

  • Thread starter Thread starter dan178
  • Start date Start date
D

dan178

Guest
I'm using compose from recompose.
compose

Code:
    // compose: https://github.com/acdlite/recompose/blob/master/docs/API.md#compose
    export function compose<TInner, TOutter>(
        ...functions: Function[]
    ): ComponentEnhancer<TInner, TOutter>;
    // export function compose<TOutter>(
    //     ...functions: Array<Function>
    // ): ComponentEnhancer<any, TOutter>;
    // export function compose(
    //     ...functions: Array<Function>
    // ): ComponentEnhancer<any, any>;

My component is being rendered inside of a Route
OperatingCompany/index.tsx

Code:
          <Routes>
            <Route path={'create'} element={<CreateOperatingCompanyContainer />} />
            <Route path={':id'} element={<OperatingCompanyDetailsContainer />} />
            <Route index element={<OperatingCompanyListContainer />} /> <------------ Here it is
          </Routes>

I have a HOC that I use to add navigate, location, and params to a component and a type that I use to add checking to the component
WithRouter/index.tsx

Code:
import { useNavigate, useLocation, useParams, Params, NavigateFunction } from 'react-router';

export type WithRouterProps<P = Params> = { // WithRouterProps
  navigate: NavigateFunction;
  location: Location;
  params: P;
};


export const withRouter = (Component) => { // withRouter
  const Wrapper = (props) => {
    const navigate = useNavigate();
    const location = useLocation();
    const params = useParams();
    return <Component location={location} params={params} navigate={navigate} {...props} />;
  };
  return Wrapper;
};

The OperatingListContainer component is being exported using compose, and has "ChildProps" for the TInner type argument with includes WithRouterProps
These are the last several lines of OperatingListContainer

Code:
type ExternalProps = any;
type ChildProps = QueryOperatingCompaniesChildProps & WithRouterProps;
export default compose<ChildProps, ExternalProps>(queryOperatingCompanies)(
  OperatingCompanyListContainer
);

These are the last several lines of queryOperatingCompanies

Code:
export function queryOperatingCompanies<P>(
  Component: React.ComponentType<P & {}>,
): React.ComponentType<P & {}> {
  return compose(queryOperatingCompaniesGraphql, renderWhileLoading())(Component);
}

My question is: why is it that typescript does not complain that I haven't wrapped the OperatingCompanyListContainer component using withRouter even though I've specified in the compose function that TInner should include WithRouterProps?

If I add WithRouterProps as part of TOutter typescript will tell me I've neglected to pass location, navigate, and params to the component but it's remains silent if WithRouterProps is in TInner and I've not used withRouter HOC to pass them. It's my understanding that TOutter are supposed to be props that are passed manually after all of the HOC's have been applied and TInner are props that should be passed via the HOC's themselves.

<p>I'm using compose from <a href="https://www.npmjs.com/package/recompose" rel="nofollow noreferrer">recompose</a>.
<br/>
<strong>compose</strong></p>
<pre><code> // compose: https://github.com/acdlite/recompose/blob/master/docs/API.md#compose
export function compose<TInner, TOutter>(
...functions: Function[]
): ComponentEnhancer<TInner, TOutter>;
// export function compose<TOutter>(
// ...functions: Array<Function>
// ): ComponentEnhancer<any, TOutter>;
// export function compose(
// ...functions: Array<Function>
// ): ComponentEnhancer<any, any>;
</code></pre>
<p>My component is being rendered inside of a Route
<br/>
<strong>OperatingCompany/index.tsx</strong></p>
<pre><code> <Routes>
<Route path={'create'} element={<CreateOperatingCompanyContainer />} />
<Route path={':id'} element={<OperatingCompanyDetailsContainer />} />
<Route index element={<OperatingCompanyListContainer />} /> <------------ Here it is
</Routes>
</code></pre>
<p>I have a HOC that I use to add navigate, location, and params to a component and a type that I use to add checking to the component
<br/>
<strong>WithRouter/index.tsx</strong></p>
<pre><code>import { useNavigate, useLocation, useParams, Params, NavigateFunction } from 'react-router';

export type WithRouterProps<P = Params> = { // WithRouterProps
navigate: NavigateFunction;
location: Location;
params: P;
};


export const withRouter = (Component) => { // withRouter
const Wrapper = (props) => {
const navigate = useNavigate();
const location = useLocation();
const params = useParams();
return <Component location={location} params={params} navigate={navigate} {...props} />;
};
return Wrapper;
};
</code></pre>
<p>The OperatingListContainer component is being exported using compose, and has "ChildProps" for the TInner type argument with includes WithRouterProps
<br/>
These are the last several lines of OperatingListContainer</p>
<pre><code>type ExternalProps = any;
type ChildProps = QueryOperatingCompaniesChildProps & WithRouterProps;
export default compose<ChildProps, ExternalProps>(queryOperatingCompanies)(
OperatingCompanyListContainer
);
</code></pre>
<p>These are the last several lines of queryOperatingCompanies
<br/></p>
<pre><code>export function queryOperatingCompanies<P>(
Component: React.ComponentType<P & {}>,
): React.ComponentType<P & {}> {
return compose(queryOperatingCompaniesGraphql, renderWhileLoading())(Component);
}
</code></pre>
<p>My question is: <strong>why is it that typescript does not complain that I haven't wrapped the OperatingCompanyListContainer component using withRouter even though I've specified in the compose function that TInner should include WithRouterProps?</strong></p>
<p>If I add WithRouterProps as part of TOutter typescript will tell me I've neglected to pass location, navigate, and params to the component but it's remains silent if WithRouterProps is in TInner and I've not used withRouter HOC to pass them. It's my understanding that TOutter are supposed to be props that are passed manually after all of the HOC's have been applied and TInner are props that should be passed via the HOC's themselves.</p>
 

Latest posts

Top