Skip to content
Advertisement

Converting React TS interface to React JS

I’m attempting to integrate this package into an app using this example. I’m not too familiar with typescript and I see that it uses interface in one of the utils (which javascript does not have). I’ve read Does JavaScript have the interface type (such as Java’s ‘interface’)?, but I’m not sure this is the same as the one typescript uses.


Here’s the TS code I am trying to convert:

import * as React from 'react'
import { Route, Redirect, RouteComponentProps } from 'react-router-dom'
import type { RouteProps } from 'react-router-dom'

import { useKeycloak } from '@react-keycloak/web'

interface PrivateRouteParams extends RouteProps {
  component:
    | React.ComponentType<RouteComponentProps<any>>
    | React.ComponentType<any>
}

export function PrivateRoute({
  component: Component,
  ...rest
}: PrivateRouteParams) {
  const { keycloak } = useKeycloak()

  return (
    <Route
      {...rest}
      render={(props) =>
        keycloak?.authenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: props.location },
            }}
          />
        )
      }
    />
  )
}

Here’s what someone suggested for JS:

import * as React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { useKeycloak } from '@react-keycloak/web';

export function PrivateRoute({ component, ...rest }) {
  const { keycloak } = useKeycloak();

  return (
    <Route
      {...rest}
      render={(props) =>
        keycloak?.authenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/auth',
              state: { from: props.location },
            }}
          />
        )
      }
    />
  );
}

Still, I don’t think that <Component /> will work in react.js.

EDIT: Added code

Advertisement

Answer

React Router takes a prop component with a lowercase c. In order to call a custom component using JSX it must have an uppercase name. See the docs

The Typescript example code renamed the prop component to Component when destructuring it. That allows them to call <Component /> using JSX.

When converting the code to Javascript you accidentally removed this renaming. You probably mistook it for a type annotation.

This code should work:

import * as React from 'react'
import { Route, Redirect } from 'react-router-dom'

import { useKeycloak } from '@react-keycloak/web'

export function PrivateRoute({
  component: Component,
  ...rest
}) {
  const { keycloak } = useKeycloak()

  return (
    <Route
      {...rest}
      render={(props) =>
        keycloak?.authenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: props.location },
            }}
          />
        )
      }
    />
  )
}
Advertisement