Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: typings seem to break with v6.4.2 #9427

Closed
liztownd opened this issue Oct 7, 2022 · 5 comments
Closed

[Bug]: typings seem to break with v6.4.2 #9427

liztownd opened this issue Oct 7, 2022 · 5 comments
Labels

Comments

@liztownd
Copy link

liztownd commented Oct 7, 2022

What version of React Router are you using?

6.4.2

Steps to Reproduce

Recently installed react-router-dom v 6.4.2 and now have errors related to typings (I'm using Typescript v 4.4.4 and @types/react-router-dom v 5.3.3). After the install I get this error related to RouteProps:

An interface can only extend an object type or intersection of object types with statically known members.

Even though when I click through the imported RouteProps it takes me to the interface and they are there in the declarations file.

From the components.d.ts file:

export declare type RouteProps = PathRouteProps | LayoutRouteProps | IndexRouteProps;

Not sure if this is a compatibility issue with the @types library but switching back to react-router-dom 6.4.1 solves the typing issue.

Expected Behavior

The code compiles and runs. :(

Actual Behavior

The compiler throws errors and the code will not compile.

Compiled with problems:X

ERROR in src/AppRoutes.ts:3:40

TS2312: An interface can only extend an object type or intersection of object types with statically known members.
    1 | import { RouteProps } from "react-router-dom";
    2 |
  > 3 | export interface AppRouteProps extends RouteProps {
      |                                        ^^^^^^^^^^
    4 |   title: string;
    5 |   // A set of properties for making a mappable list
    6 |   url?: string;

@liztownd liztownd added the bug label Oct 7, 2022
@timdorr
Copy link
Member

timdorr commented Oct 7, 2022

Looks like this was changed to a union type in #9366.

@brophdawg11
Copy link
Contributor

Ah - yeah we moved to discriminated unions for all of our RouteObject/RouteProps types so we could detect and error if you tried to add children to index routes (something we already error at runtime for, so we're just extending that safety back to compile type in TS now)

Example of an invalid route setup:

<Route index element={<Index />}>
  <Route ... />
</Route>

Can you adjust your types to use the following?

export type AppRouteProps = RouteProps & { ... }

@liztownd
Copy link
Author

Yes, it will technically work now with that fix.

@artuska
Copy link

artuska commented Nov 20, 2022

"react-router-dom": "6.4.3"
"typescript": "4.9.3"

How do i type children prop with AppRouterProps? This does not work:

import { RouteObject } from 'react-router-dom';

import { UserRole } from 'modules/User/user.types';

export type AppRouteObject = RouteObject & {
  children?: AppRouteObject[];
  roles?: UserRole[];
};

Above type throws me an error in createBrowserRouter function:

Object literal may only specify known properties, and 'roles' does not exist in type 'RouteObject'.

Now i have to write this hack:

export type AppRouteObject = RouteObject & {
  children?: any;
  roles?: UserRole[];
};

@brophdawg11
Copy link
Contributor

@artuska If you override the RouteObject union type directly we would lose the mutual exclusivity of index routes and children. Instead, I would override the union types directly and recreate your own union, thus preserving the index/children type safety:

type IndexAppRouteObject = IndexRouteObject & {
  roles?: string[];
};

type NonIndexAppRouteObject = NonIndexRouteObject & {
  children?: AppRouteObject[];
  roles?: string[];
};

type AppRouteObject = IndexAppRouteObject | NonIndexAppRouteObject;

I set up a working example of this in https://codesandbox.io/s/extending-route-object-2dqjc8?file=/src/index.tsx - does this handle your use case?

6.4 also introduces the handle field on routes which you can put whatever you want inside of and is also accessible via useMatches so tat may be potentially useful as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants