UNPKG

class-constructor

Version:

Tool to implement builder pattern that actually uses class constructor with ease

131 lines (122 loc) 4.74 kB
interface OptionalBuilderPropertyMetadata { desiredPropertyKey: string; } /** * Represents an abstract class constructor type. * @template T The instance type of the class, defaults to any * @returns A constructor type that creates instances of T */ type Clazz<T = any> = abstract new (...args: any[]) => T; /** * Represents a concrete (instantiable) class constructor type. * @template T The instance type of the class, defaults to any * @returns A constructor type that creates instances of T */ type InstantiableClazz<T = any> = new (...args: any[]) => T; type StringPropertyKeyParameterDecorator = (target: Object, propertyKey: string) => void; /** * Interface for a fluent builder pattern. * Provides getter/setter methods for each optional property and a build() method. * * @typeParam TOptionals - Type containing optional properties that can be set * @typeParam TClass - The class type being built * * @example * ```typescript * interface Options { * optionalProperty?: string; * } * * const builder: Builder<Options, MyClass> = MyClass.builder('required'); * const instance = builder * .optionalProperty('value') // Set value * .optionalProperty() // Get current value * .build(); // Create instance * ``` */ type Builder<TOptionals, TClass> = { [K in keyof TOptionals]-?: ((arg: TOptionals[K]) => Builder<TOptionals, TClass>) & (() => TOptionals[K]); } & { build(): TClass; }; /** * Utility type that extracts the instance type from a class constructor. * @template T The class constructor type * @returns The instance type of the class */ type ClassInstance<T> = T extends InstantiableClazz<infer U> ? U : never; interface BuilderObject<TClass extends InstantiableClazz = any> { instance: any; [key: string]: ((value: unknown) => BuilderObject<TClass>) | (() => unknown); build: () => ClassInstance<TClass>; } /** * Creates a builder for a class with required constructor parameters and optional properties. * * @param classConstructor - The class to build * @param parameters - Required constructor parameters * @returns A builder instance that provides fluent methods for setting optional properties * */ declare function ParametrizedBuilder<TClass extends InstantiableClazz, TOptionals = ClassInstance<TClass>>(classConstructor: TClass, parameters: ConstructorParameters<TClass>): Builder<TOptionals, ClassInstance<TClass>>; /** * Decorator that specifies custom getter and setter functions for a builder property. * This allows customizing how properties are accessed and modified during the build process. * * @param get - Function to get the property value from the target object * @param set - Function to set the property value on the target object * @returns PropertyDecorator function * * @example * ```typescript * class MyClass { * @BuilderAccessors( * (target) => target._property, * (target, value) => target.property = value * ) * private _property?: string; * * set property(value: string) { * this._property = value.toUpperCase(); * } * } * ``` */ declare function BuilderAccessors<T extends object, V>(get: (target: T) => V, set: (target: T, value: V) => void): (target: T, propertyKey: string) => void; interface BuilderMethodFactory<TClass extends InstantiableClazz> { withOptionals<TOptionals>(): (...args: ConstructorParameters<TClass>) => Builder<TOptionals, ClassInstance<TClass>>; classAsOptionals(): (...args: ConstructorParameters<TClass>) => Builder<ClassInstance<TClass>, ClassInstance<TClass>>; } /** * Creates a builder method factory for a class that can generate builders with different optional property configurations. * * @param clazz - The class to create a builder for * @returns A factory object with methods to create different types of builders * * @example * ```typescript * * interface MyOptionals { * optional?: string; * } * * class MyClass { * constructor(public required: string) {} * private _optional?: string; * * static builder = toBuilderMethod(MyClass).withOptionals<MyOptionals>(); * } * ``` * @example * ```typescript * * class MyClass { * constructor(public required: string) {} * public optional?: string; * * static builder = toBuilderMethod(MyClass).classAsOptionals(); * } * ``` */ declare function toBuilderMethod<TClass extends InstantiableClazz>(clazz: TClass): BuilderMethodFactory<TClass>; export { type Builder, BuilderAccessors, type BuilderMethodFactory, type BuilderObject, type ClassInstance, type Clazz, type InstantiableClazz, type OptionalBuilderPropertyMetadata, ParametrizedBuilder, type StringPropertyKeyParameterDecorator, toBuilderMethod };