function checkType(value, expectedType, propName) { if (typeof value !== expectedType) { throw new Error(`Invalid ${propName} type. Expected ${expectedType}.`); } } function checkInstance(value, expectedInstance) { if (!(value instanceof expectedInstance)) { const expectedName = expectedInstance.constructor.name; throw new Error(`Invalid type. Expected ${expectedName} instance.`); } } class Person { constructor(id, name, age, isActive, hobbies, address) { checkType(id, 'number', "id"); checkType(name, 'string', "name"); checkType(age, 'number', "age"); checkType(isActive, 'boolean', "isActive"); checkType(hobbies, 'object', "hobbies"); checkInstance(address, Address); this.id = id; this.name = name; this.age = age; this.isActive = isActive; this.hobbies = hobbies; this.address = address; } } class Address { constructor(city, country, street) { checkType(city, 'string', "city"); checkType(country, 'string', "country"); checkInstance(street, Street); this.city = city; this.country = country; this.street = street; } } class Street { constructor(name, number, apartment) { checkType(name, 'string', "name"); checkType(number, 'number', "number"); checkInstance(apartment, Apartment); this.name = name; this.number = number; this.apartment = apartment; } } class Apartment { constructor(floor, number) { checkType(floor, 'number', "floor"); checkType(number, 'number', "number"); this.floor = floor; this.number = number; } } class PersonBuilder { constructor(personData) { const person = this.#buildPerson(personData); Object.assign(this, person); } #buildApartment(apartmentData) { const { floor, number } = apartmentData; return new Apartment(floor, number); } #buildStreet(streetData) { const { name, number, apartment } = streetData; const apartmentObj = this.#buildApartment(apartment); return new Street(name, number, apartmentObj); } #buildAddress(addressData) { const { city, country, street } = addressData; const streetObj = this.#buildStreet(street); return new Address(city, country, streetObj); } #buildPerson(personData) { const { id, name, age, isActive, hobbies, address } = personData; const addressObj = this.#buildAddress(address); return new Person(id, name, age, isActive, hobbies, addressObj); } } const personData = { id: 1, name: 'John Doe', age: 30, isActive: true, hobbies:{}, address: { city: 'Cityville', country: 'Countryland', street: { name: 'Main Street', number: 123, apartment: { floor: 2, number: 201 } } } }; const personBuilder = new PersonBuilder(personData); console.log(personBuilder);
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter