Skip to content

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

@gdebunne

Description

@gdebunne

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions