From ea4bc04e9489c456e2b4b5dbd67d5e4cf3f89f97 Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Wed, 10 Jul 2024 07:05:13 -0400 Subject: [PATCH] feat: `ActionReturnType` (#11443) * feat: ActionReturnType util * feat(test): ActionReturnType * chore: changeset --- .changeset/small-vans-own.md | 29 +++++++++++++++++++ .../src/actions/runtime/virtual/server.ts | 2 ++ .../astro/test/types/action-return-type.ts | 18 ++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 .changeset/small-vans-own.md create mode 100644 packages/astro/test/types/action-return-type.ts diff --git a/.changeset/small-vans-own.md b/.changeset/small-vans-own.md new file mode 100644 index 0000000000..06352e256a --- /dev/null +++ b/.changeset/small-vans-own.md @@ -0,0 +1,29 @@ +--- +'astro': patch +--- + +Expose new `ActionReturnType` utility from `astro:actions`. This infers the return type of an action by passing `typeof actions.name` as a type argument. This example defines a `like` action that returns `likes` as an object: + +```ts +// actions/index.ts +import { defineAction } from 'astro:actions'; + +export const server = { + like: defineAction({ + handler: () => { + /* ... */ + return { likes: 42 } + } + }) +} +``` + +In your client code, you can infer this handler return value with `ActionReturnType`: + +```ts +// client.ts +import { actions, ActionReturnType } from 'astro:actions'; + +type LikesResult = ActionReturnType; +// -> { likes: number } +``` diff --git a/packages/astro/src/actions/runtime/virtual/server.ts b/packages/astro/src/actions/runtime/virtual/server.ts index 500336f754..c034be8bc8 100644 --- a/packages/astro/src/actions/runtime/virtual/server.ts +++ b/packages/astro/src/actions/runtime/virtual/server.ts @@ -19,6 +19,8 @@ type Handler = TInputSchema extends z.ZodType ? (input: z.infer, context: ActionAPIContext) => MaybePromise : (input: any, context: ActionAPIContext) => MaybePromise; +export type ActionReturnType> = Awaited>; + export type ActionClient< TOutput, TAccept extends Accept | undefined, diff --git a/packages/astro/test/types/action-return-type.ts b/packages/astro/test/types/action-return-type.ts new file mode 100644 index 0000000000..4ca66eed25 --- /dev/null +++ b/packages/astro/test/types/action-return-type.ts @@ -0,0 +1,18 @@ +import { describe, it } from 'node:test'; +import { expectTypeOf } from 'expect-type'; +import { type ActionReturnType, defineAction } from '../../dist/actions/runtime/virtual/server.js'; +import { z } from '../../zod.mjs'; + +describe('ActionReturnType', () => { + it('Infers action return type', async () => { + const action = defineAction({ + input: z.object({ + name: z.string(), + }), + handler: async ({ name }) => { + return { name }; + }, + }); + expectTypeOf>().toEqualTypeOf<{ name: string }>(); + }); +});