Skip to content

Type incompatibility between history and createReactRouterV5Options (ReactRouterHistory) #1824

@chrisharbro

Description

@chrisharbro

Description

When instrumenting a React application that uses react-router v5 and history v4, TypeScript reports a type incompatibility for the history option passed to createReactRouterV5Options.

This appears to be a mismatch between the history@4 types and the ReactRouterHistory type defined in @grafana/faro-react.

Steps to reproduce

Try to instrument a product using react-router 5 with the following code:

Note: Code sanitized, collector URL and environment details redacted for customer privacy.

const history = createBrowserHistory();

initializeFaro({
  // Mandatory, the URL of the Grafana collector
  url: 'https://faro-collector.example.com/collect/<redacted>',

  // Mandatory, the identification label of your application
  app: {
    name: 'foobar',
    version: '0.0.0',
    environment: 'production',
  },

  sessionTracking: {
    samplingRate: 1,
    persistent: true,
  },
  instrumentations: [
    // Mandatory, omits default instrumentations otherwise.
    ...getWebInstrumentations(),

    // Tracing package to get end-to-end visibility for HTTP requests.
    new TracingInstrumentation(),

    new ReactIntegration({
      // or createReactRouterV4Options
      router: createReactRouterV5Options({
        history, // the history object used by react-router
        Route, // Route component imported from react-router package
      }),
    }),
  ],
});

Expected behavior

The history object created by createBrowserHistory() should be accepted by createReactRouterV5Options without requiring a manual type assertion.

Actual behavior

TypeScript fails with the following error:

Type 'History<unknown>' is not assignable to type 'ReactRouterHistory'.
  Types of property 'listen' are incompatible.
    Type '(listener: LocationListener<unknown>) => UnregisterCallback' is not assignable to type '(cb: (location: ReactRouterLocation<unknown>, action: NavigationType) => void) => void'.
      Types of parameters 'listener' and 'cb' are incompatible.
        Types of parameters 'location' and 'location' are incompatible.
          Type 'Location<unknown>' is not assignable to type 'ReactRouterLocation<unknown>'.
            Types of property 'key' are incompatible.
              Type 'string | undefined' is not assignable to type 'string'.
                Type 'undefined' is not assignable to type 'string'.

Workaround

Casting the history object resolves the error:

const history = createBrowserHistory() as ReactRouterHistory;

Environment

    "@grafana/faro-react": "^2.1.0",
    "@grafana/faro-web-tracing": "^2.1.0",
    "history": "^4.10.1",
    "react-router": "^5.3.4",
    "react-router-dom": "^5.3.0",
    "@types/history": "^4.7.11",

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugReport a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions