diff --git a/cli/tsc/dts/lib.deno.ns.d.ts b/cli/tsc/dts/lib.deno.ns.d.ts index cbf86eec66a231..084dc1b76a87e5 100644 --- a/cli/tsc/dts/lib.deno.ns.d.ts +++ b/cli/tsc/dts/lib.deno.ns.d.ts @@ -6256,6 +6256,35 @@ declare namespace Deno { info: ServeHandlerInfo, ) => Response | Promise; + /** Interface that module run with `deno serve` subcommand must conform to. + * + * To ensure your code is type-checked properly, make sure to add `satisfies Deno.ServeDefaultExport` + * to the `export default { ... }` like so: + * + * ```ts + * export default { + * fetch(req) { + * return new Response("Hello world"); + * } + * } satisfies Deno.ServeDefaultExport; + * ``` + * + * @category HTTP Server + */ + export interface ServeDefaultExport { + /** A handler for HTTP requests. Consumes a request and returns a response. + * + * If a handler throws, the server calling the handler will assume the impact + * of the error is isolated to the individual request. It will catch the error + * and if necessary will close the underlying connection. + * + * @category HTTP Server + */ + fetch: ( + request: Request, + ) => Response | Promise; + } + /** Options which can be set when calling {@linkcode Deno.serve}. * * @category HTTP Server diff --git a/tests/specs/serve/type_check/__test__.jsonc b/tests/specs/serve/type_check/__test__.jsonc new file mode 100644 index 00000000000000..813eafc12f91f3 --- /dev/null +++ b/tests/specs/serve/type_check/__test__.jsonc @@ -0,0 +1,6 @@ +{ + "args": "serve --check --port 12345 main.ts", + "output": "main.out", + "tempDir": true, + "exitCode": 1 +} diff --git a/tests/specs/serve/type_check/main.out b/tests/specs/serve/type_check/main.out new file mode 100644 index 00000000000000..4613ef265c7889 --- /dev/null +++ b/tests/specs/serve/type_check/main.out @@ -0,0 +1,5 @@ +Check [WILDCARD] +error: TS2353 [ERROR]: Object literal may only specify known properties, and 'bad' does not exist in type 'ServeDefaultExport'. + bad() { + ~~~ + at [WILDCARD]main.ts:2:3 diff --git a/tests/specs/serve/type_check/main.ts b/tests/specs/serve/type_check/main.ts new file mode 100644 index 00000000000000..10ba18337854e6 --- /dev/null +++ b/tests/specs/serve/type_check/main.ts @@ -0,0 +1,4 @@ +export default { + bad() { + }, +} satisfies Deno.ServeDefaultExport; diff --git a/tests/specs/serve/type_check2/__test__.jsonc b/tests/specs/serve/type_check2/__test__.jsonc new file mode 100644 index 00000000000000..813eafc12f91f3 --- /dev/null +++ b/tests/specs/serve/type_check2/__test__.jsonc @@ -0,0 +1,6 @@ +{ + "args": "serve --check --port 12345 main.ts", + "output": "main.out", + "tempDir": true, + "exitCode": 1 +} diff --git a/tests/specs/serve/type_check2/main.out b/tests/specs/serve/type_check2/main.out new file mode 100644 index 00000000000000..259acb85b797a7 --- /dev/null +++ b/tests/specs/serve/type_check2/main.out @@ -0,0 +1,5 @@ +Check [WILDCARD] +error: TS2339 [ERROR]: Property 'doesnt_exist' does not exist on type 'Request'. + console.log(request.doesnt_exist); + ~~~~~~~~~~~~ + at [WILDCARD]main.ts:3:25 diff --git a/tests/specs/serve/type_check2/main.ts b/tests/specs/serve/type_check2/main.ts new file mode 100644 index 00000000000000..41cbf30ec56e48 --- /dev/null +++ b/tests/specs/serve/type_check2/main.ts @@ -0,0 +1,6 @@ +export default { + fetch(request) { + console.log(request.doesnt_exist); + return new Response("Hello world!"); + }, +} satisfies Deno.ServeDefaultExport;