# validated() function · @imqueue/validation

Source: https://imqueue.org/api/validation/latest/validation.validated/
Published: 2026-08-01
Author: @imqueue maintainers (https://github.com/imqueue)
Package: @imqueue/validation 1.1.0 — generated reference, not hand-written

Method decorator that checks a method's positional arguments before the method body runs — the usual way to validate an `@imqueue/rpc` service method's input.

**Signature:**

```typescript
export declare function validated(...validators: Validator[]): <T extends (...args: never[]) => unknown>(method: T, context: ClassMethodDecoratorContext) => T;
```

## Parameters


| Parameter | Type | Description |
| --- | --- | --- |
| validators | [Validator](https://imqueue.org/api/validation/latest/validation.validator/)\[\] | One [Validator](https://imqueue.org/api/validation/latest/validation.validator/) per positional argument, in order. |


**Returns:**

<T extends (...args: never\[\]) => unknown>(method: T, context: ClassMethodDecoratorContext) => T

The TC39 method decorator that wraps the method in the check.

## Exceptions

Error if applied to anything other than a method.

ZodError from Zod itself, unwrapped, on the first argument that fails. That instance is what an in-process caller catches. A remote one catches nothing of the kind: `@imqueue/rpc` turns any thrown error into its own payload, so the client sees the code `IMQ_RPC_CALL_ERROR` and Zod's issue list as a message string. Test `instanceof ZodError` locally; read the message remotely.

## Remarks

One validator per parameter, left to right. `null` or `undefined` skips that position, and any argument past the end of the list is not checked at all. A validator does still run at a position the caller left empty, against `undefined`, so it fails there unless the schema is optional.

This validates and nothing more: the method receives the argument the caller passed, never the value Zod returned. A schema that transforms rather than merely checks therefore has no effect on the method body — `z.string().trim()` confirms the string is trimmable and hands over the untrimmed original, `z.coerce.number()` accepts `'42'` while the parameter stays the string `'42'`, `.default(...)` fills nothing in, and an object schema leaves undeclared properties in place instead of stripping them. Where the converted value is what the method needs, parse it in the body.

Validators are resolved once, on the first call rather than when the decorator runs, and memoized from then on. What that defers is the schema assembly, not the reference to the class: a [validatable()](https://imqueue.org/api/validation/latest/validation.validatable/) class named here must still be declared above this method, or the decorator argument hits the temporal dead zone and throws `ReferenceError` at class-definition time.

## Example


```typescript
class UserService {
    // Validate the first argument against a sealed input class and the second
    // against a bare schema; skip the third.
    @validated(Credentials, z.string().min(2), null)
    async signUp(creds: Credentials, name: string, meta?: unknown) {
        // creds and name are known-good here
    }
}
```

