Skip to Content

Customization

Codables provides flexible customization options for controlling how your classes are serialized and deserialized.

Key Mapping

Use the keys option to map properties to different names during serialization:

@codableClass("User", { keys: { firstName: "first_name", lastName: "last_name", emailAddress: "email" } }) class User { firstName: string; lastName: string; emailAddress: string; constructor(data: Pick<User, "firstName" | "lastName" | "emailAddress">) { this.firstName = data.firstName; this.lastName = data.lastName; this.emailAddress = data.emailAddress; } } const coder = new Coder([User]); const user = new User({ firstName: "John", lastName: "Doe", emailAddress: "john@example.com" }); const encoded = coder.encode(user); // { $$User: [{ first_name: "John", last_name: "Doe", email: "john@example.com" }] } const decoded = coder.decode<User>(encoded); // decoded.firstName === "John" (mapped back correctly)

Property-Level Key Mapping

You can also map individual properties using the @codable() decorator:

@codableClass("Product") class Product { @codable("product_id") id: string; @codable("product_name") name: string; @codable("price_in_cents") price: number; constructor(data: Pick<Product, "id" | "name" | "price">) { this.id = data.id; this.name = data.name; this.price = data.price; } } const coder = new Coder([Product]); const product = new Product({ id: "prod-123", name: "Widget", price: 1999 }); const encoded = coder.encode(product); // { $$Product: [{ product_id: "prod-123", product_name: "Widget", price_in_cents: 1999 }] }

Combining Key Mappings

Class-level and property-level mappings work together:

@codableClass("Order", { keys: { orderDate: "date", totalAmount: "total" } }) class Order { @codable("order_id") id: string; orderDate: Date; totalAmount: number; constructor(data: Pick<Order, "id" | "orderDate" | "totalAmount">) { this.id = data.id; this.orderDate = data.orderDate; this.totalAmount = data.totalAmount; } } const coder = new Coder([Order]); const order = new Order({ id: "order-456", orderDate: new Date(), totalAmount: 99.99 }); const encoded = coder.encode(order); // { $$Order: [{ order_id: "order-456", date: "2025-01-01T00:00:00.000Z", total: 99.99 }] }

Custom Encoding/Decoding

For complex customization needs, provide custom encode function.

Encode function must return an array of arguments matching the constructor of your class.

@codableClass("ComplexType", { encode: (instance) => { // Must return an array of arguments matching the constructor of your class. // TypeScript will guard you here return [instance.getSome(), instance.getOther()] } }) class ComplexType { // ... class properties ... // Constructor is not memberwise - Codables is not able to know how to construct the instance from the encoded data. constructor(some: string, other: number) { // Custom constructor logic } }

Selective Property Encoding

Instead of using @codable() decorator, you can use keys option to specify exactly which properties to encode.

@codableClass("SelectiveType", { keys: ["name", "email"] }) class SelectiveType { name: string; email: string; password: string; // Not encoded internalId: string; // Not encoded constructor(data: Memberwise<SelectiveType, "name" | "email">) { this.name = data.name; this.email = data.email; } }
Last updated on