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/corebun add @ts-kizuna/corenpm install @ts-kizuna/coreimport { isValidationError } from '@ts-kizuna/core';
// also re-exported from @ts-kizuna/fetchParameters
isValidationError(body: unknown): body is ValidationError| Parameter | Type | Description |
|---|---|---|
body | unknown | Any 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.