UNPKG

@tsed/schema

Version:
91 lines (90 loc) 2.37 kB
import { cleanObject } from "@tsed/core"; /** * Manages discriminator mappings for polymorphic type resolution. * * A discriminator enables polymorphism in schemas by using a specific property * value to determine which subtype schema to apply. This is essential for * inheritance hierarchies and union types in OpenAPI specifications. * * ### Concept * * When a base class has multiple derived classes, the discriminator property * (e.g., "type", "kind") indicates which concrete class an object represents. * * ### Usage * * ```typescript * // Base class * @DiscriminatorKey("type") * abstract class Animal { * type: string; * } * * // Derived classes * @DiscriminatorValue("dog") * class Dog extends Animal { * breed: string; * } * * @DiscriminatorValue("cat") * class Cat extends Animal { * indoor: boolean; * } * ``` * * ### OpenAPI Mapping * * Generates OpenAPI discriminator objects: * ```json * { * "discriminator": { * "propertyName": "type", * "mapping": { * "dog": "#/components/schemas/Dog", * "cat": "#/components/schemas/Cat" * } * } * } * ``` * * ### Key Features * * - **Type Mapping**: Maps discriminator values to TypeScript classes * - **Bidirectional Lookup**: Find type by value or values by type * - **Default Values**: Get the default discriminator value for a type * - **Children Discovery**: List all derived types * * @public */ export class Discriminator { constructor({ base, propertyName, types, values } = {}) { this.values = new Map(); this.types = new Map(); Object.assign(this, cleanObject({ base, propertyName, types: types ? new Map(types) : undefined, values: values ? new Map(values) : undefined })); } add(type, values) { values.forEach((value) => { this.values.set(value, type); }); this.types.set(type, values); return this; } getType(discriminatorValue) { return this.values.get(discriminatorValue) || this.base; } getValues(type) { return this.types.get(type); } getDefaultValue(type) { const values = this.types.get(type); return values ? values[0] : undefined; } children() { return [...new Set([...this.types.keys()])]; } }