Repository: remix-run/react-router
File: packages/router/utils.ts (TypeScript)

Code before:
 * Arguments passed to action functions
 */
export interface ActionFunctionArgs extends DataFunctionArgs {}

/**
 * Loaders and actions can return anything except `undefined` (`null` is a
 * valid return value if there is no data to return).  Responses are preferred
 * and will ease any future migration to Remix
 */
type DataFunctionValue = Response | NonNullable<unknown> | null;

/**
 * Route loader function signature
 */
export interface LoaderFunction {
  (args: LoaderFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
}

/**
 * Route action function signature
 */
export interface ActionFunction {
  (args: ActionFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
}

/**
 * Arguments passed to shouldRevalidate function
 */
export interface ShouldRevalidateFunctionArgs {
  currentUrl: URL;
  currentParams: AgnosticDataRouteMatch["params"];
  nextUrl: URL;
  nextParams: AgnosticDataRouteMatch["params"];
  formMethod?: Submission["formMethod"];
  formAction?: Submission["formAction"];
  formEncType?: Submission["formEncType"];
  text?: Submission["text"];
  formData?: Submission["formData"];
  json?: Submission["json"];
  actionResult?: any;
  defaultShouldRevalidate: boolean;
}

/**
 * Route shouldRevalidate function signature.  This runs after any submission
 * (navigation or fetcher), so we flatten the navigation/fetcher submission
 * onto the arguments.  It shouldn't matter whether it came from a navigation
 * or a fetcher, what really matters is the URLs and the formData since loaders
 * have to re-run based on the data models that were potentially mutated.
 */
export interface ShouldRevalidateFunction {

Review comment (suggestion):
```suggestion
export interface ActionFunction<Context = any> {
  (args: ActionFunctionArgs<Context>): Promise<DataFunctionValue> | DataFunctionValue;
```

Code after:
export interface LoaderFunctionArgs<C = any> extends DataFunctionArgs<C> {}

/**
 * Arguments passed to action functions
 */
export interface ActionFunctionArgs<C = any> extends DataFunctionArgs<C> {}

/**
 * Loaders and actions can return anything except `undefined` (`null` is a
 * valid return value if there is no data to return).  Responses are preferred
 * and will ease any future migration to Remix
 */
type DataFunctionValue = Response | NonNullable<unknown> | null;

/**
 * Route loader function signature
 */
export interface LoaderFunction<C = any> {
  (args: LoaderFunctionArgs<C>): Promise<DataFunctionValue> | DataFunctionValue;
}

/**
 * Route action function signature
 */
export interface ActionFunction<C = any> {
  (args: ActionFunctionArgs<C>): Promise<DataFunctionValue> | DataFunctionValue;
}

/**
 * Arguments passed to shouldRevalidate function
 */
export interface ShouldRevalidateFunctionArgs {
  currentUrl: URL;
  currentParams: AgnosticDataRouteMatch["params"];
  nextUrl: URL;
  nextParams: AgnosticDataRouteMatch["params"];
  formMethod?: Submission["formMethod"];
  formAction?: Submission["formAction"];
  formEncType?: Submission["formEncType"];
  text?: Submission["text"];
  formData?: Submission["formData"];
  json?: Submission["json"];
  actionResult?: any;
  defaultShouldRevalidate: boolean;
}

/**
 * Route shouldRevalidate function signature.  This runs after any submission
 * (navigation or fetcher), so we flatten the navigation/fetcher submission
 * onto the arguments.  It shouldn't matter whether it came from a navigation
 * or a fetcher, what really matters is the URLs and the formData since loaders