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]: Typescript 5.x error when using exactOptionalPropertyTypes #10392

Open
Tracked by #1622
gdebunne opened this issue Apr 24, 2023 · 1 comment
Open
Tracked by #1622

[Bug]: Typescript 5.x error when using exactOptionalPropertyTypes #10392

gdebunne opened this issue Apr 24, 2023 · 1 comment
Labels

Comments

@gdebunne
Copy link

What version of React Router are you using?

6.10.0

Steps to Reproduce

Start from the <RouteProvider> test case above.

Edit package.json and set typescript version to 5.0.4.

Edit tsconfig.json :

  • add "exactOptionalPropertyTypes": true
  • set skipLibCheck to false
  • remove the deprecated importsNotUsedAsValues option

Reload project to make sure it is updated.

Open a new terminal and run npm run build to run tsc

Expected Behavior

react-router ts files compile with no error

Actual Behavior

node_modules/react-router/dist/lib/components.d.ts:54:30 - error TS2344: Type 'NonIndexRouteObject' does not satisfy the constraint 'AgnosticRouteObject'.

54     lazy?: LazyRouteFunction<NonIndexRouteObject>;
                                ~~~~~~~~~~~~~~~~~~~

node_modules/react-router/dist/lib/components.d.ts:73:30 - error TS2344: Type 'IndexRouteObject' does not satisfy the constraint 'AgnosticRouteObject'.

73     lazy?: LazyRouteFunction<IndexRouteObject>;
                                ~~~~~~~~~~~~~~~~

node_modules/react-router/dist/lib/context.d.ts:19:30 - error TS2344: Type 'IndexRouteObject' does not satisfy the constraint 'AgnosticRouteObject'.
  Type 'IndexRouteObject' is not assignable to type 'AgnosticIndexRouteObject' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
    Type 'IndexRouteObject' is not assignable to type 'AgnosticBaseRouteObject' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
      Types of property 'caseSensitive' are incompatible.
        Type 'boolean | undefined' is not assignable to type 'boolean'.

Details on the (recommended) exactOptionalPropertyTypes option are available here

In AgnosticBaseRouteObject, caseSensitive is declared as an optional boolean property : caseSensitive?: boolean;

In IndexRouteObject, its declaration is caseSensitive?: AgnosticIndexRouteObject["caseSensitive"]; which translates to caseSensitive?: boolean | undefined;

When using this TS option, a property with a possibly undefined value is not the same as a possibly undefined property. The two types are hence considered incompatible.

A possible fix is to declare caseSensitive?: NotUndefined<AgnosticNonIndexRouteObject["caseSensitive"]>;
where type NotUndefined<T> = T extends undefined ? never : T

@hornta
Copy link

hornta commented Mar 15, 2024

I also run into this. I have the same flag enabled and I got this code. TypeScript want's me to either pass search as a string OR not pass it at all, but in my case, search has the type string | undefined and so it complains.

let search: string | undefined = ...;
navigate({
  pathname: `/${result.data.id}`,
  search,
})

I suggest changing the type of To to something like:

type PartialWithExplicitUndefined<T> = {
    [P in keyof T]?: T[P] | undefined;
};

type To = string | PartialWithExplicitUndefined<Path>;

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

2 participants