diff --git a/.changeset/short-lizards-rescue.md b/.changeset/short-lizards-rescue.md
new file mode 100644
index 000000000..cda21aeb2
--- /dev/null
+++ b/.changeset/short-lizards-rescue.md
@@ -0,0 +1,5 @@
+---
+"openapi-fetch": patch
+---
+
+Improve `Middleware` type definition to require either onRequest or onResponse
diff --git a/packages/openapi-fetch/src/index.d.ts b/packages/openapi-fetch/src/index.d.ts
index c2e9ebda3..a2bab4ff7 100644
--- a/packages/openapi-fetch/src/index.d.ts
+++ b/packages/openapi-fetch/src/index.d.ts
@@ -144,12 +144,22 @@ export interface MiddlewareCallbackParams {
   readonly options: MergedOptions;
 }
 
-export interface Middleware {
-  onRequest?: (options: MiddlewareCallbackParams) => void | Request | undefined | Promise<Request | undefined | void>;
-  onResponse?: (
-    options: MiddlewareCallbackParams & { response: Response },
-  ) => void | Response | undefined | Promise<Response | undefined | void>;
-}
+type MiddlewareOnRequest = (
+  options: MiddlewareCallbackParams,
+) => void | Request | undefined | Promise<Request | undefined | void>;
+type MiddlewareOnResponse = (
+  options: MiddlewareCallbackParams & { response: Response },
+) => void | Response | undefined | Promise<Response | undefined | void>;
+
+export type Middleware =
+  | {
+      onRequest: MiddlewareOnRequest;
+      onResponse?: MiddlewareOnResponse;
+    }
+  | {
+      onRequest?: MiddlewareOnRequest;
+      onResponse: MiddlewareOnResponse;
+    };
 
 /** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */
 export type MaybeOptionalInit<Params, Location extends keyof Params> = RequiredKeysOf<
diff --git a/packages/openapi-fetch/test/middleware/middleware.test.ts b/packages/openapi-fetch/test/middleware/middleware.test.ts
index 1ac49e751..a13ee8c57 100644
--- a/packages/openapi-fetch/test/middleware/middleware.test.ts
+++ b/packages/openapi-fetch/test/middleware/middleware.test.ts
@@ -1,4 +1,4 @@
-import { expect, test } from "vitest";
+import { expect, test, expectTypeOf, assertType } from "vitest";
 import { createObservedClient } from "../helpers.js";
 import type { Middleware, MiddlewareCallbackParams } from "../../src/index.js";
 import type { paths } from "./schemas/middleware.js";
@@ -354,3 +354,12 @@ test("auth header", async () => {
   });
   expect(headers.get("authorization")).toBe(`Bearer ${accessToken}`);
 });
+
+test("type error occurs only when neither onRequest nor onResponse is specified", async () => {
+  expectTypeOf<Middleware>().not.toEqualTypeOf({});
+  const onRequest = async ({ request }: MiddlewareCallbackParams) => request;
+  const onResponse = async ({ response }: MiddlewareCallbackParams & { response: Response }) => response;
+  assertType<Middleware>({ onRequest });
+  assertType<Middleware>({ onResponse });
+  assertType<Middleware>({ onRequest, onResponse });
+});