API Reference

isValidationError

Type guard to distinguish kizuna validation errors from custom 400 responses on the client.

Type guard to distinguish kizuna validation errors from custom 400 responses on the client.

pnpm add @ts-kizuna/core
bun add @ts-kizuna/core
npm install @ts-kizuna/core
import { isValidationError } from '@ts-kizuna/core';
// also re-exported from @ts-kizuna/fetch

Parameters

isValidationError(body: unknown): body is ValidationError
ParameterTypeDescription
bodyunknownAny value to check

Returns

true if body is a ValidationError, narrowing the type for TypeScript.

ValidationError shape

An RFC 9457 Problem Details body with an errors extension:

interface ValidationError {
    type: string;
    title: string;
    status: number;
    detail: string;
    errors: Array<{
        code: ValidationIssueCode;
        path: string[];
        message: string;
    }>;
}

code is typed as ValidationIssueCode, so the built-in Zod codes are offered as autocomplete suggestions, while any custom string (e.g. one emitted via k.issue) is still assignable.

Common error codes: invalid_type, too_small, too_big, invalid_string_format, unrecognized_keys, not_multiple_of, custom. To emit your own machine-readable code from a .superRefine() check, see k.issue.

Example

When a route declares its own 400 response, the client sees a union of your type and ValidationError. Use isValidationError to distinguish them:

import { isValidationError } from '@ts-kizuna/fetch';

const result = await client.users.createUser({
    body: {
        name: '',
        email: 'not-an-email',
    },
});

if (result.status === 400) {
    if (isValidationError(result.body)) {
        for (const error of result.body.errors) {
            console.log(error.code, error.path, error.message);
        }
    } else {
        console.error(result.body.detail);
    }
}

If a route does not declare a 400 response, you don't need this, because result.status === 400 narrows the body to ValidationError directly.

See the Fetch client guide for more details.

On this page