diff --git a/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/react-router-dom_v6.x.x.js b/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/react-router-dom_v6.x.x.js index 8ac393d817..b5344cf08b 100644 --- a/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/react-router-dom_v6.x.x.js +++ b/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/react-router-dom_v6.x.x.js @@ -8,6 +8,14 @@ declare module 'react-router-dom' { // `@remix-run/router` / // ----------------------------------/ + declare type FutureConfig = {| + v7_normalizeFormMethod: boolean, + |}; + + declare type RouteData = {| + [routeId: string]: any, + |}; + declare type To = LocationShape | string; declare export type Location = $ReadOnly<{ @@ -382,10 +390,46 @@ declare module 'react-router-dom' { handle: Handle, |}>; + /** + * Returns the nearest ancestor Route error, which could be a loader/action + * error or a render error. This is intended to be called from your + * ErrorBoundary/errorElement to display a proper error message. + */ + declare export function useRouteError(): any; + + /** + * Returns the loader data for the nearest ancestor Route loader + */ + declare export function useLoaderData(): any; + + declare export type RouterProviderProps = {| + fallbackElement?: React$Node; + router: typeof Router; + |} + + declare export function RouterProvider(RouterProviderProps): React$Node; + // ----------------------------------/ // `react-router-dom` / // ----------------------------------/ + declare type DOMRouterOpts = {| + basename?: string, + future?: FutureConfig, + hydrationData?: {| + loaderData?: RouteData, + actionData?: RouteData | null, + errors?: RouteData | null, + |}, + // Should be Window type but flow doesn't have this + window?: any, + |}; + + declare export function createBrowserRouter( + routes: Array, + opts?: DOMRouterOpts + ): typeof Router; + declare type URLSearchParamsInit = | string | Array<[string, string]> diff --git a/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/test_react-router-dom.js b/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/test_react-router-dom.js index 4882e5b19a..d2b40b64fc 100644 --- a/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/test_react-router-dom.js +++ b/definitions/npm/react-router-dom_v6.x.x/flow_v0.104.x-/test_react-router-dom.js @@ -1,6 +1,8 @@ // @flow import React from 'react'; import { + createBrowserRouter, + RouterProvider, BrowserRouter, HashRouter, Link, @@ -21,6 +23,8 @@ import { useParams, useRouteMatch, useMatches, + useRouteError, + useLoaderData, } from 'react-router-dom'; import type { AgnosticRouteMatch, @@ -403,10 +407,82 @@ describe('react-router-dom', () => { }); }); + describe('useRouteError', () => { + // It is described as any in the type def, but unknown the actual library + (useRouteError(): string); + + // $FlowExpectedError[extra-arg] it takes no args + useRouteError('test'); + }); + + describe('useLoaderData', () => { + // It is described as any in the type def, but unknown the actual library + (useLoaderData(): string); + + // $FlowExpectedError[extra-arg] it takes no args + useLoaderData('test'); + }); + // ----------------------------------/ // `react-router-dom` / // ----------------------------------/ + describe('RouterProvider use case', () => { + it('works', () => { + const router = createBrowserRouter([ + { + path: "/", + element:
Hello world!
, + }, + ]); + + (() => ( + + )) + }); + + it('catches createBrowserRouter error usages', () => { + // $FlowExpectedError[incompatible-call] + createBrowserRouter(); + // $FlowExpectedError[incompatible-cast] + (createBrowserRouter([]): string); + // $FlowExpectedError[incompatible-call] + createBrowserRouter('test'); + + createBrowserRouter([], {}); + createBrowserRouter([], { + basename: 'test', + future: { + v7_normalizeFormMethod: true, + }, + hydrationData: { + loaderData: { a: 1 }, + actionData: { a: 1 }, + errors: null, + }, + window: {}, + }); + + createBrowserRouter([], { + // $FlowExpectedError[incompatible-call] + basename: 1, + }); + // $FlowExpectedError[prop-missing] + createBrowserRouter([], { + // $FlowExpectedError[prop-missing] + future: { + a: 1, + }, + }); + createBrowserRouter([], { + hydrationData: { + // $FlowExpectedError[incompatible-call] + loaderData: null, + }, + }); + }); + }); + describe('BrowserRouter', () => { it('works', () => {