Categories
TypeScript Answers

How to mock the useHistory hook in Jest and TypeScript?

Sometimes, we want to mock the useHistory hook in Jest and TypeScript.

In this article, we’ll look at how to mock the useHistory hook in Jest and TypeScript.

How to mock the useHistory hook in Jest and TypeScript?

To mock the useHistory hook in Jest and TypeScript, we can mock the react-router-dom module.

For instance, we write

jest.mock("react-router-dom", () => ({
  useHistory: () => ({
    push: jest.fn(),
  }),
}));

in our test file to call jest.mock with the module name and a function that returns the mocked module contents.

In the object returned, we add the useHistory property and set it to a function that returns an object that has the push function set to a mock function returned by jest.fn.

Conclusion

To mock the useHistory hook in Jest and TypeScript, we can mock the react-router-dom module.

Categories
TypeScript Answers

How to fix the “Property does not exist on type ‘DetailedHTMLProps, HTMLDivElement>'” error with React and TypeScript?

To fix the "Property does not exist on type ‘DetailedHTMLProps, HTMLDivElement>’" error with React and TypeScript, we can extend the react module’s types using a declare statement.

For instance, in a .d.ts file, we write

declare module "react" {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    custom?: string;
  }
}

to add the custom property into the HTMLAttributes interface.

Then we can add the custom attribute into the HTML elements in our React project.

Categories
TypeScript Answers

How to add the type for Image with TypeScript?

Sometimes, we want to add the type for Image with TypeScript.

In this article, we’ll look at how to add the type for Image with TypeScript.

How to add the type for Image with TypeScript?

To add the type for Image with TypeScript, we should use the HTMLImageElement for Image instances.

For instance, we write

const image: HTMLImageElement = new Image();

to set image to the HTMLImageElement.

Image files selected from an input should have the File type and URL strings for images should have the string type.

Conclusion

To add the type for Image with TypeScript, we should use the HTMLImageElement for Image instances.

Categories
TypeScript Answers

How to rewrite the protected routes using TypeScript and React-Router 5?

Sometimes, we want to rewrite the protected routes using TypeScript and React-Router 5.

In this article, we’ll look at how to rewrite the protected routes using TypeScript and React-Router 5.

How to rewrite the protected routes using TypeScript and React-Router 5?

To rewrite the protected routes using TypeScript and React-Router 5, we can define our own prop type for our route component.

For instance, we write

import { Redirect, Route, RouteProps } from "react-router";

type ProtectedRouteProps = {
  isAuthenticated: boolean;
  authenticationPath: string;
} & RouteProps;

export default function ProtectedRoute({
  isAuthenticated,
  authenticationPath,
  ...routeProps
}: ProtectedRouteProps) {
  if (isAuthenticated) {
    return <Route {...routeProps} />;
  } else {
    return <Redirect to={{ pathname: authenticationPath }} />;
  }
}

to define the ProtectedRouteProps type that has the prop properties that we defined.

And then we combine that with RouteProps by creating an intersection type with it with &.

Then ProtectedRouteProps should have the props from both types.

And then we can use the props without TypeScript compiler errors.

Conclusion

To rewrite the protected routes using TypeScript and React-Router 5, we can define our own prop type for our route component.

Categories
TypeScript Answers

How to rewrite the protected routes using TypeScript and React-Router 6?

Sometimes, we want to rewrite the protected routes using TypeScript and React-Router 6.

In this article, we’ll look at how to rewrite the protected routes using TypeScript and React-Router 6.

How to rewrite the protected routes using TypeScript and React-Router 6?

To rewrite the protected routes using TypeScript and React-Router 6, we can define the type for the route props ourselves.

For instance, we write

export type ProtectedRouteProps = {
  isAuthenticated: boolean;
  authenticationPath: string;
  outlet: JSX.Element;
};

export default function ProtectedRoute({
  isAuthenticated,
  authenticationPath,
  outlet,
}: ProtectedRouteProps) {
  if (isAuthenticated) {
    return outlet;
  } else {
    return <Navigate to={{ pathname: authenticationPath }} />;
  }
}

to define the ProtectedRouteProps with some properties for the ProtectedRoute component props.

Then we can destructure the props and use them in the component.

We render outlet, which has the route component if isAuthenticated is true.

Next, we can use ProtectedRoute by writing

const App = () => {
  //...
  const defaultProtectedRouteProps: Omit<ProtectedRouteProps, "outlet"> = {
    isAuthenticated: !!sessionContext.isAuthenticated,
    authenticationPath: "/login",
  };

  return (
    <div>
      <Routes>
        <Route path="/" element={<Homepage />} />
        <Route
          path="dashboard"
          element={
            <ProtectedRoute
              {...defaultProtectedRouteProps}
              outlet={<Dashboard />}
            />
          }
        />
        <Route
          path="nested"
          element={
            <ProtectedRoute
              {...defaultProtectedRouteProps}
              outlet={<Layout />}
            />
          }
        >
          <Route path="one" element={<Protected />} />
          <Route path="two" element={<Protected />} />
        </Route>
        <Route path="login" element={<Login />} />
      </Routes>
    </div>
  );
};

to add the protected routes with the ProtectedRoute component by setting them as values for the Route component’s element prop.

Conclusion

To rewrite the protected routes using TypeScript and React-Router 6, we can define the type for the route props ourselves.