Repository: unjs/h3
Pull request #791 (2024-06-25 08:58:32)

fix(types)!: default `body` types to `unknown`
Addresses a pending todo in anticipation of next major.



Patch:
diff --git a/src/handler.ts b/src/handler.ts
index bcb2982..c83838c 100644
--- a/src/handler.ts
+++ b/src/handler.ts
@@ -14,9 +14,12 @@ import type {
 import { _kRaw } from "./event";
 import { hasProp } from "./utils/internal/object";
 
-type _EventHandlerHooks = {
-  onRequest?: RequestMiddleware[];
-  onBeforeResponse?: ResponseMiddleware[];
+type _EventHandlerHooks<
+  Request extends EventHandlerRequest = EventHandlerRequest,
+  Response extends EventHandlerResponse = EventHandlerResponse,
+> = {
+  onRequest?: RequestMiddleware<Request>[];
+  onBeforeResponse?: ResponseMiddleware<Request, Response>[];
 };
 
 export function defineEventHandler<
@@ -55,28 +58,31 @@ export function defineEventHandler<
     return handler;
   }
   // Object Syntax
-  const _hooks: _EventHandlerHooks = {
+  const _hooks: _EventHandlerHooks<Request, Response> = {
     onRequest: _normalizeArray(handler.onRequest),
     onBeforeResponse: _normalizeArray(handler.onBeforeResponse),
   };
-  const _handler: EventHandler<Request, any> = (event) => {
+  const _handler: EventHandler<Request, any> = (event: H3Event) => {
     return _callHandler(event, handler.handler, _hooks);
   };
   _handler.__is_handler__ = true;
   _handler.__resolve__ = handler.handler.__resolve__;
   _handler.__websocket__ = handler.websocket;
-  return _handler;
+  return _handler as EventHandler<Request, Response>;
 }
 
 function _normalizeArray<T>(input?: T | T[]): T[] | undefined {
   return input ? (Array.isArray(input) ? input : [input]) : undefined;
 }
 
-async function _callHandler(
+async function _callHandler<
+  Request extends EventHandlerRequest = EventHandlerRequest,
+  Response extends EventHandlerResponse = EventHandlerResponse,
+>(
   event: H3Event,
-  handler: EventHandler,
-  hooks: _EventHandlerHooks,
-) {
+  handler: EventHandler<Request, Response>,
+  hooks: _EventHandlerHooks<Request, Response>,
+): Promise<Awaited<Response> | undefined> {
   if (hooks.onRequest) {
     for (const hook of hooks.onRequest) {
       await hook(event);
diff --git a/src/types/handler.ts b/src/types/handler.ts
index 4a0ded5..8692e4b 100644
--- a/src/types/handler.ts
+++ b/src/types/handler.ts
@@ -2,10 +2,10 @@ import type { QueryObject } from "ufo";
 import type { H3Event } from "./event";
 import type { Hooks as WSHooks } from "crossws";
 
-export type EventHandlerResponse<T = any> = T | Promise<T>;
+export type EventHandlerResponse<T = unknown> = T | Promise<T>;
 
 export interface EventHandlerRequest {
-  body?: any; // TODO: Default to unknown in next major version
+  body?: unknown;
   query?: QueryObject;
   routerParams?: Record<string, string>;
 }
diff --git a/src/types/utils/static.ts b/src/types/utils/static.ts
index c4b19f4..f6cfc67 100644
--- a/src/types/utils/static.ts
+++ b/src/types/utils/static.ts
@@ -1,3 +1,5 @@
+import type { RawResponse } from "../event";
+
 export interface StaticAssetMeta {
   type?: string;
   etag?: string;
@@ -18,7 +20,7 @@ export interface ServeStaticOptions {
   /**
    * This function should resolve asset content
    */
-  getContents: (id: string) => any | Promise<any>;
+  getContents: (id: string) => RawResponse | Promise<RawResponse>;
 
   /**
    * Map of supported encodings (compressions) and their file extensions.
diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts
index ecddc12..47a24ed 100644
--- a/src/utils/proxy.ts
+++ b/src/utils/proxy.ts
@@ -158,7 +158,7 @@ export function getProxyRequestHeaders(event: H3Event) {
  */
 export function fetchWithEvent<
   T = unknown,
-  _R = any,
+  _R = unknown,
   F extends (req: RequestInfo | URL, opts?: any) => any = typeof fetch,
 >(
   event: H3Event,


Test patch:
diff --git a/test/types.test-d.ts b/test/types.test-d.ts
index 211d47a..5e04991 100644
--- a/test/types.test-d.ts
+++ b/test/types.test-d.ts
@@ -22,8 +22,7 @@ describe("types", () => {
           expectTypeOf(event).toEqualTypeOf<H3Event>();
 
           const body = await readJSONBody(event);
-          // TODO: Default to unknown in next major version
-          expectTypeOf(body).toBeAny();
+          expectTypeOf(body).toBeUnknown();
 
           return {
             foo: "bar",
@@ -57,8 +56,7 @@ describe("types", () => {
     it("untyped", () => {
       eventHandler(async (event) => {
         const body = await readJSONBody(event);
-        // TODO: Default to unknown in next major version
-        expectTypeOf(body).toBeAny();
+        expectTypeOf(body).toBeUnknown();
       });
     });