From afed051253c51f33fe8dc7a759a97f36e5a1f1f1 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Sun, 16 Apr 2023 09:38:24 +1000 Subject: [PATCH 1/5] add missing types --- .../flow_v0.104.x-/react-router-dom_v6.x.x.js | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) 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..9b609a6abb 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 @@ -1,4 +1,6 @@ declare module 'react-router-dom' { + import type { Node as ReactNode } from 'react'; + // NOTE: Below are duplicated from react-router // A work in progress of refactoring will move related types to their own // package definition as the main branch of flow-typed is able to handle this @@ -8,6 +10,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<{ @@ -220,6 +230,13 @@ declare module 'react-router-dom' { // `react-router` / // ----------------------------------/ + declare export type RouterProviderProps = {| + fallbackElement?: ReactNode; + router: Router; + |} + + declare export function RouterProvider(RouterProviderProps): ReactNode; + declare export type IndexRouteObject = {| caseSensitive?: AgnosticIndexRouteObject['caseSensitive'], path?: AgnosticIndexRouteObject['path'], @@ -386,6 +403,23 @@ declare module 'react-router-dom' { // `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 + ): Router; + declare type URLSearchParamsInit = | string | Array<[string, string]> From 00dd3f84b0fec7a184d00c48d2fce679c22c74b3 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Sun, 16 Apr 2023 11:06:39 +1000 Subject: [PATCH 2/5] correct definition --- .../flow_v0.104.x-/react-router-dom_v6.x.x.js | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) 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 9b609a6abb..5f4871bec5 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 @@ -1,6 +1,4 @@ declare module 'react-router-dom' { - import type { Node as ReactNode } from 'react'; - // NOTE: Below are duplicated from react-router // A work in progress of refactoring will move related types to their own // package definition as the main branch of flow-typed is able to handle this @@ -230,13 +228,6 @@ declare module 'react-router-dom' { // `react-router` / // ----------------------------------/ - declare export type RouterProviderProps = {| - fallbackElement?: ReactNode; - router: Router; - |} - - declare export function RouterProvider(RouterProviderProps): ReactNode; - declare export type IndexRouteObject = {| caseSensitive?: AgnosticIndexRouteObject['caseSensitive'], path?: AgnosticIndexRouteObject['path'], @@ -399,11 +390,18 @@ declare module 'react-router-dom' { handle: Handle, |}>; + declare export type RouterProviderProps = {| + fallbackElement?: React$Node; + router: typeof Router; + |} + + declare export function RouterProvider(RouterProviderProps): React$Node; + // ----------------------------------/ // `react-router-dom` / // ----------------------------------/ - declare type DOMRouterOpts = { + declare type DOMRouterOpts = {| basename?: string, future?: FutureConfig, hydrationData?: {| @@ -413,12 +411,12 @@ declare module 'react-router-dom' { |}, // Should be Window type but flow doesn't have this window?: any, - }; + |}; declare export function createBrowserRouter( routes: Array, opts?: DOMRouterOpts - ): Router; + ): typeof Router; declare type URLSearchParamsInit = | string From e29ea98989057c94c1ebf9add39e12b83ca7ff08 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Sun, 16 Apr 2023 11:18:37 +1000 Subject: [PATCH 3/5] add tests --- .../flow_v0.104.x-/react-router-dom_v6.x.x.js | 6 +- .../flow_v0.104.x-/test_react-router-dom.js | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) 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 5f4871bec5..3c99f906be 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 @@ -405,9 +405,9 @@ declare module 'react-router-dom' { basename?: string, future?: FutureConfig, hydrationData?: {| - loaderData: RouteData, - actionData: RouteData | null, - errors: RouteData | null, + loaderData?: RouteData, + actionData?: RouteData | null, + errors?: RouteData | null, |}, // Should be Window type but flow doesn't have this window?: any, 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..53ffef9d51 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, @@ -407,6 +409,62 @@ describe('react-router-dom', () => { // `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', () => { From a626fe4ecf8f4c21f2a30842b421c4f0c0e7ad92 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Sun, 16 Apr 2023 11:26:46 +1000 Subject: [PATCH 4/5] add missing useRouteError --- .../flow_v0.104.x-/react-router-dom_v6.x.x.js | 7 +++++++ .../flow_v0.104.x-/test_react-router-dom.js | 9 +++++++++ 2 files changed, 16 insertions(+) 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 3c99f906be..f7b26b93ae 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 @@ -390,6 +390,13 @@ 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; + declare export type RouterProviderProps = {| fallbackElement?: React$Node; router: typeof Router; 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 53ffef9d51..95bb5898ea 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 @@ -23,6 +23,7 @@ import { useParams, useRouteMatch, useMatches, + useRouteError, } from 'react-router-dom'; import type { AgnosticRouteMatch, @@ -405,6 +406,14 @@ 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'); + }); + // ----------------------------------/ // `react-router-dom` / // ----------------------------------/ From 3c2238a927a00c186f5614fa70f678e17540c60f Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Sun, 16 Apr 2023 11:30:22 +1000 Subject: [PATCH 5/5] add missing useLoaderData --- .../flow_v0.104.x-/react-router-dom_v6.x.x.js | 5 +++++ .../flow_v0.104.x-/test_react-router-dom.js | 9 +++++++++ 2 files changed, 14 insertions(+) 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 f7b26b93ae..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 @@ -397,6 +397,11 @@ declare module 'react-router-dom' { */ 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; 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 95bb5898ea..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 @@ -24,6 +24,7 @@ import { useRouteMatch, useMatches, useRouteError, + useLoaderData, } from 'react-router-dom'; import type { AgnosticRouteMatch, @@ -414,6 +415,14 @@ describe('react-router-dom', () => { 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` / // ----------------------------------/