Infer types
Learn how to infer types with next-cool-action.
Infer types
next-cool-action, since version 7.6.4, exports utility types for type inference. Here's a guide on how to use them.
Suppose we have declared this cool action client:
import { z } from "zod";
import { createCoolActionClient, createMiddleware } from "next-cool-action";
import { getSessionData } from "@/services/auth"
// Here we declare a standalone auth middleware.
export const authMiddleware = createMiddleware<{
ctx: { sessionToken: string };
metadata: { actionName: string };
}>().define(async ({ ctx, next }) => {
const { sessionId, userId } = await getSessionData(ctx.sessionToken);
return next({
ctx: {
sessionId,
userId,
},
});
});
// Here we declare the cool action client.
export const actionClient = createCoolActionClient({
defineMetadataSchema: () => {
return z.object({
actionName: z.string(),
});
},
handleServerError: (e) => {
console.error("Action error:", e.message);
return {
errorMessage: e.message,
};
},
})
.use(async ({ next }) => {
return next({
ctx: {
sessionToken: "someToken",
},
});
})
.use(authMiddleware);And then this action function:
"use server";
import { z } from "zod";
import { actionClient } from "@/lib/cool-action";
const testActionSchema = z.object({
username: z.string(),
});
const testActionBindArgsSchemas: [email: z.ZodString, age: z.ZodNumber] = [z.string(), z.number()];
export const testAction = actionClient
.use(authMiddleware)
.inputSchema(testActionSchema)
.bindArgsSchemas(testActionBindArgsSchemas)
.action(async () => {
return {
successful: true,
};
});We'll use these exported functions in the following examples.
/
The library exports several utility types from the root path that help you infer types of a cool action client, a middleware function or a cool action function.
Here's the list of utility types exported from next-cool-action path:
InferCoolActionFnInput: infer input types of a cool action functionInferCoolActionFnResult: infer result type of a cool action functionInferMiddlewareFnNextCtx: infer the type of context returned by a middleware function using thenextfunctionInferCtx: infer the type of context of a cool action client, or the context passed to a middleware functionInferMetadata: infer the type of metadata of a cool action client or middleware functionInferServerError: infer the type of theserverErrorof a cool action function, middleware function or cool action function
Example
import type {
InferCtx,
InferMetadata,
InferMiddlewareFnNextCtx,
InferCoolActionFnInput,
InferCoolActionFnResult,
InferServerError,
} from "next-cool-action";
import type { actionClient, authMiddleware } from "@/lib/cool-action";
import type { testAction } from "@/app/test-action";
// Use `InferCoolActionFnInput` to infer the input types of a cool action function.
type inferredTestActionInput = InferCoolActionFnInput<typeof testAction>;
/*
{
clientInput: {
username: string;
};
bindArgsClientInputs: [email: string, age: number];
parsedInput: {
username: string;
};
bindArgsParsedInputs: [email: string, age: number];
}
*/
// Use `InferCoolActionFnResult` to infer the result type of a cool action function.
type inferredTestActionResult = InferCoolActionFnResult<typeof testAction>;
/*
{
data?: {
successful: boolean;
} | undefined;
serverError?: string | undefined;
validationErrors?: {
_errors?: string[];
username?: {
_errors?: string[];
} | undefined;
} | undefined;
bindArgsValidationErrors?: [email: { _errors?: string[] }, age: { _errors?: string[] }] | undefined;
}
*/
// Use `InferMiddlewareFnNextCtx` to infer the type of the context returned by a middleware function using
// the `next` function.
type inferredAuthMiddlewareNextCtx = InferMiddlewareFnNextCtx<typeof authMiddleware>;
/*
{
sessionId: string;
userId: string;
}
*/
// Use `InferCtx` to infer the type of the context of a cool action client, or the context passed to a
// middleware function. Here's an example with a cool action client:
type inferredCoolActionClientCtx = InferCtx<typeof actionClient>;
/*
{
sessionToken: string;
} & {
sessionId: string;
userId: string;
}
*/
// Use `InferMetadata` to infer the type of the metadata of a cool action client or middleware function.
// Here's an example with a middleware function:
type inferredMiddlewareMetadata = InferMetadata<typeof authMiddleware>;
/*
{
actionName: string;
}
*/
// Use `InferServerError` to infer the type of the `serverError` of a cool action client, middleware function,
// or cool action function. Here's an example with a cool action:
type inferredServerError = InferServerError<typeof testAction>;
/*
{
errorMessage: string;
}
*//hooks
The library also exports three types from the /hooks path that help you infer types when using useAction, useOptimisticAction and useStateAction hooks.
Here's a list of utility types exported from next-cool-action/hooks:
InferUseActionHookReturn: infers the return type of theuseActionhook - only works with actions defined using theactionmethodInferUseOptimisticActionHookReturn: infers the return type of theuseOptimisticActionhook - only works with stateless actions defined using theactionmethodInferUseStateActionHookReturn- DEPRECATED: infers the return type of theuseStateActionhook - only works with stateful actions defined using thestateActionmethod
Example
import type { testAction } from "@/app/test-action";
// Use `InferUseActionHookReturn` to infer the return type of the `useAction` hook with a provided
// cool action function.
type inferredTestActionHookReturn = InferUseActionHookReturn<typeof testAction>;
/*
{
execute: (input: { username: string }) => void;
executeAsync: (input: { username: string }) => Promise<CoolActionResult>;
input: { username: string };
result: CoolActionResult;
reset: () => void;
status: HookActionStatus;
} & HookShorthandStatus
*/
// Use `InferUseActionHookReturn` to infer the return type of the `useOptimisticAction` hook with a provided
// cool action function. You can pass the server state as the second generic parameter, which defaults
// to `any`.
type inferredTestActionOptimisticHookReturn = InferUseOptimisticActionHookReturn<
typeof testAction,
{ myServerState: { foo: string } }
>;
/*
{
execute: (input: { username: string }) => void;
executeAsync: (input: { username: string }) => Promise<CoolActionResult>;
input: { username: string };
result: CoolActionResult;
reset: () => void;
status: HookActionStatus;
optimisticState: { myServerState: { foo: string } };
} & HookShorthandStatus
*/
// Use `InferUseStateActionHookReturn` to infer the return type of the `useStateAction` hook with a
// provided stateful cool action. In this case, by providing the type of `testAction` as the
// generic parameter will, the resulting type will be `never`, because `testAction` is not defined
// using `stateAction()` method. Supposing that we change the definition of the function to be stateful,
// the resulting type will be:
type inferredTestActionStateHookReturn = InferUseStateActionHookReturn<typeof testAction>;
/*
{
execute: (input: { username: string }) => void;
input: { username: string };
result: CoolActionResult;
status: HookActionStatus;
} & HookShorthandStatus
*/