Skip to content

andreas-hellmann/ts-generic-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Type-safe and generic implementation of the build pattern in Typescript

How to use it

Simple usage

  • Conditions:
    • No methods in class
    • No need to keep properties private and controlling object manipulation
// Usage of the Builder
const person: Person = new Builder(Person)
    .with({ firstname: 'Magne' })
    .with({ surname: 'Thor' })
    .with({ birthday: new Date('2000-01-11') })
    .build();


// Optional implementation of the Validatable interface. Builder calls validate() *BEFORE* an object is build.
class Person implements Validatable {
    public readonly title?: string;
    public readonly firstname: string;
    public readonly surname: string;
    public readonly birthday?: Date;

    constructor(builder: Builder<Person> & Person) {
        this.title = builder.title;
        this.firstname = builder.firstname;
        this.surname = builder.surname;
        this.birthday = builder.birthday;
    }

    validate(): boolean {
        // Do your validation here
        return true;
    }
}

Usage in the context of Domain Driven Design

  • Use cases:
    • Model is implemented in domain driven fassion, that is class contains methods which are encapsulating business logic
    • Property access is kept private to enforce object manipulation through business logic methods
// Usage of the DomainBuilder
const correctVo: PersonVo = new DomainBuilder(PersonVo)
    .with({ firstname: 'Magne' })
    .with({ surname: 'Thor' })
    .with({ birthday: new Date('2000-01-11') })
    .build();

// Model definition
interface PersonProps extends Validatable {
    readonly title?: string;
    readonly firstname: string;
    readonly surname: string;
    readonly birthday?: Date;
}

export class PersonVo implements PersonProps {
    private _title?: string;
    private _firstname: string;
    private _surname: string;
    private _birthday?: Date;

    constructor(builder: DomainBuilder<PersonProps, PersonVo> & PersonProps) {
        this._title = builder.title;
        this._firstname = builder.firstname;
        this._surname = builder.surname;
        this._birthday = builder.birthday;
    }

    get title(): string | undefined {
        return this._title;
    }
    get firstname(): string {
        return this._firstname;
    }
    get surname(): string {
        return this._surname;
    }
    get birthday(): Date | undefined {
        return this._birthday;
    }

    validate(): boolean {
        // Do your validation here
        return true;
    }

    public changeSurname(newName: string): void {
        this._surname = newName;
    }
}

Implementation of Validatable interface

Implement the Validatable interface if you want to run validations before the builder creates the object.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors