@@ -318,6 +318,43 @@ function useIsomorphicLayoutEffect(
318318 * middle of a page, and you don't want it to scroll to the top when a tab is
319319 * clicked.
320320 *
321+ * ### Return Type Augmentation
322+ *
323+ * Internally, `useNavigate` uses a separate implementation when you are in
324+ * Declarative mode versus Data/Framework mode - the primary difference being
325+ * that the latter is able to return a stable reference that does not change
326+ * identity across navigations. The implementation in Data/Framework mode also
327+ * returns a `Promise` that resolves when the navigation is completed. This means
328+ * the return type of `useNavigate` is `void | Promise<void>`. This is accurate,
329+ * but can lead to some red squigglies based on the union in the return value:
330+ *
331+ * - If you're using `typescript-eslint`, you may see errors from
332+ * [`@typescript-eslint/no-floating-promises`](https://typescript-eslint.io/rules/no-floating-promises/)
333+ * - In Framework/Data mode, `React.use(navigate())` will show a false-positive
334+ * `Argument of type 'void | Promise<void>' is not assignable to parameter of
335+ * type 'Usable<void>'` error
336+ *
337+ * The easiest way to work around these issues is to augment the type based on the
338+ * router you're using:
339+ *
340+ * ```ts
341+ * // If using <BrowserRouter>
342+ * declare module "react-router" {
343+ * interface NavigateFunction {
344+ * (to: To, options?: NavigateOptions): void;
345+ * (delta: number): void;
346+ * }
347+ * }
348+ *
349+ * // If using <RouterProvider> or Framework mode
350+ * declare module "react-router" {
351+ * interface NavigateFunction {
352+ * (to: To, options?: NavigateOptions): Promise<void>;
353+ * (delta: number): Promise<void>;
354+ * }
355+ * }
356+ * ```
357+ *
321358 * @public
322359 * @category Hooks
323360 * @returns A navigate function for programmatic navigation
0 commit comments