Speakeasy Logo
Skip to Content

Model validation and serialization

Speakeasy TypeScript SDKs support model validation and serialization backed by Zod. This feature enables validation of data against models and easy serialization or deserialization of data to and from JSON.

Example

As an example, consider the following model definition:

<sdk-root>/src/models/components/book.ts
import * as z from "zod"; export type Book = { /** * The unique identifier for the book */ id: string; /** * The title of the book */ title: string; /** * The author of the book */ author: string; };

From JSON

example.ts
import { bookFromJSON, bookToJSON } from "my-sdk/models/components/book"; const result = bookFromJSON('{"id":"1","title":"1984","author":"George Orwell"}'); if (result.ok) { console.log(result.value); // 👆 result.value is of type `Book` } else { // Handle validation errors console.error(result.error); }

To JSON

example.ts
const jsonString = bookToJSON({ id: "1", title: "1984", author: "George Orwell" }); // jsonString is of type `string`

Forward compatibility and fault tolerance

Speakeasy TypeScript SDKs are designed to handle API evolution gracefully. The deserialization layer includes several features that make SDKs more resilient to changes in API responses.

Forward-compatible enums

Enums in responses automatically accept unknown values, so new enum values added by the API won’t break existing SDK users. Unknown values are captured in a type-safe Unrecognized<string> wrapper. Configure this behavior with forwardCompatibleEnumsByDefault in your gen.yaml, or control individual enums with x-speakeasy-unknown-values: allow or x-speakeasy-unknown-values: disallow in your OpenAPI spec.

Forward-compatible unions

Discriminated unions accept unknown discriminator values, capturing them with their raw data accessible via the UNKNOWN discriminator value. Configure this with forwardCompatibleUnionsByDefault: tagged-only in your gen.yaml.

Lax mode

When laxMode: lax is enabled (the default), the SDK gracefully handles missing or mistyped fields by filling in sensible zero-value defaults rather than failing deserialization. This ensures SDKs continue working even when API responses don’t perfectly match the expected schema, while maintaining type safety.

Smart union deserialization

The unionStrategy: populated-fields setting (enabled by default) picks the union option with the most matching fields, making deserialization more robust when union types aren’t well-discriminated.

For more details, see the forward compatibility documentation and the TypeScript configuration reference.

Last updated on