AxaFrance / oidc-client

Light, Secure, Pure Javascript OIDC (Open ID Connect) Client. We provide also a REACT wrapper (compatible NextJS, etc.).
MIT License
597 stars 160 forks source link

withOidcSecure types break React.FC components with props #633

Closed taylormck closed 2 years ago

taylormck commented 3 years ago

Issue and Steps to Reproduce

When trying to use withOidcSecure to wrap a component that takes props, a typescript error prevents compilation.

Here's a simple example to reproduce:

import React from 'react';
import { withOidcSecure } from '@axa-fr/react-oidc-context';

type FooProps = {
  bar: string;
};

const Foo: React.FC<FooProps> = ({ bar }) => <>{bar}</>;

const SecureFoo = withOidcSecure(Foo);

This will produce the following error:

Argument of type 'FC<FooProps>' is not assignable to parameter of type 'ComponentType<{}>'.
  Type 'FunctionComponent<FooProps>' is not assignable to type 'FunctionComponent<{}>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type '{ children?: ReactNode; }' is not assignable to type 'PropsWithChildren<FooProps>'.
        Property 'bar' is missing in type '{ children?: ReactNode; }' but required in type 'FooProps'.

This is likely caused by both this library and React.FC using the PropsWithChildren type to wrap their props.

This can be a particular problem when trying to secure pages that take parameters, such as taking URL parameters with React Router:

// App.tsx
import React, { useEffect } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import FooPage from './pages/foo/[bar]';

const App: React.FC = () => (
  <Router>
    <Switch>
      <Route path="/foo/:bar" Component={FooPage} />
    </Switch>
  </Router>
);

export default App;

// pages/foo/[bar].tsx
import React from 'react';
import { RouteComponentProps } from 'react-router-dom'
import { withOidcSecure } from '@axa-fr/react-oidc-context';

type FooProps = {
  bar: string;
};

type PageProps = RouteComponentProps<FooProps>;

const Foo: React.FC<PageProps> = ({ match }) => <>{match.params.bar}</>;

const SecureFoo = withOidcSecure(Foo);

Versions

Currently using 3.1.6

Screenshots

Screen Shot 2021-06-07 at 11 16 57

Expected

Expected the typescript component to compile successfully.

Actual

The typescript component does not compile successfully.

Additional Details

This can be worked around by basically recreating the HOC locally:

import React from 'react';
import { OidcSecure } from '@axa-fr/react-oidc-context';

type FooProps = {
  bar: string;
};

const Foo: React.FC<FooProps> = ({ bar }) => <>{bar}</>;

export const SecureFoo = (props) => (
  <OidcSecure>
    <Foo {...props} />
  </OidcSecure>
);
guillaume-chervet commented 3 years ago

Thank you very much for that issue

guillaume-chervet commented 2 years ago

Do you still have the problem on v4?

guillaume-chervet commented 2 years ago

I close the issue, feel free to reopen it if you have the problem in the v4. It should work now. Thank you very much.