What is the process for implementing a decorator pattern using typescript?

I'm on a quest to dynamically create instances of various classes without the need to explicitly define each one. My ultimate goal is to implement the decorator pattern, but I've hit a roadblock in TypeScript due to compilation limitations.

Despite my efforts with Proxies, I haven't had much luck.

Below is a snippet of the usage I'm aiming for (though some crucial code is missing to enable me to achieve what I have in mind - this is the puzzle I'm currently working on).

class Person {

    public name: string;
    public age: number;

    public identify() {
        console.log(`${this.name} age ${this.age}`);
    }


}

class Child {

    public Mother: Person;
    public Father: Person;

    public logParents() {
        console.log("Parents:");
        this.Mother.identify();
        this.Father.identify();
    }

}

class Student {

    public school: string;

    public logSchool() {
        console.log(this.school);
    }

}

let Dad = new Person();
Dad.name = "Brad";
Dad.age = 32;

let Mom = new Person();
Mom = new Student(Mom);
Mom.name = "Janet";
Mom.age = 34;
Mom.school = "College of Night School Moms";

let Johnny = new Person();
Johnny = new Child(Johnny);
Johnny = new Student(Johnny);
Johnny.name = "Johnny";
Johnny.age = 12;
Johnny.Mother = Mom;
Johnny,Father = Dad;
Johnny.school = "School for kids who can't read good";

Answer №1

After reviewing the java example provided here, I made some adjustments to better align with your code:

interface Person {
    name: string;
    age: number;
    identify(): void;
}

class SimplePerson implements Person {
    public name: string;
    public age: number;

    public identify(){
        console.log(`${this.name} is ${this.age} years old`);
    }
}

abstract class PersonDecorator implements Person {
    protected decoratedPerson: Person;

    public constructor(person: Person) {
        this.decoratedPerson = person;
    }

    public get name() {
        return this.decoratedPerson.name;
    }

    public get age() {
        return this.decoratedPerson.age;
    }

    identify(): void {
        return this.decoratedPerson.identify();
    }
}

class Child extends PersonDecorator {
    public Mother: Person;
    public Father: Person;

    public logParents(){
        console.log("Parent Details:");
        this.Mother.identify();
        this.Father.identify();
    }
}

class Student extends PersonDecorator {
    public school:string;

    public logSchool(){
        console.log(this.school);
    }
}

let Dad = new SimplePerson();
Dad.name = "Brad";
Dad.age = 32;

let Mom = new SimplePerson();
Mom = new Student(Mom);
Mom.name = "Janet";
Mom.age = 34;
(Mom as Student).school = "College of Night School Moms";

let Johnny = new SimplePerson();
Johnny = new Child(Johnny);
Johnny = new Student(Johnny);
Johnny.name = "Johnny";
Johnny.age = 12;
(Johnny as Child).Mother = Mom;
(Johnny as Child).Father = Dad;
(Johnny as Student).school = "School for kids who can't read well";

(You can check out the full code demo on playground)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What methods can be used to center a Google map on a specific location?

I am facing an issue with three map canvases on different divs. Despite setting the center to the same position in all three of them using JavaScript, the second and third maps do not seem to reflect that center. Does anyone have any insights on what cou ...

What is the best way for library creators to indicate to VSCode which suggested "import" is the correct one?

As a library creator, I have noticed that VSCode often suggests incorrect imports to users. For instance, VSCode typically suggests the following import: import useTranslation from 'next-translate/lib/esm/useTranslation' However, the correct im ...

Tips for steering clear of getting caught in the initial focus trap

I have implemented Focus-trap (https://www.npmjs.com/package/focus-trap) in my modal to enhance keyboard accessibility. Here is a snippet of my code: <FocusTrap focusTrapOptions={{onDeactivate: onClose}} > <div> ... </div> <Focu ...

How can one get rid of a sudden strong beginning?

Recently, I delved into the world of CSS animation and encountered a frustrating issue. I've tried numerous methods and workarounds to achieve a smoothly looping animation without interruptions. Despite my efforts, I have not been able to replicate th ...

How should dynamic route pages be properly managed in NextJS?

Working on my first project using NextJS, I'm curious about the proper approach to managing dynamic routing. I've set up a http://localhost:3000/trips route that shows a page with a list of cards representing different "trips": https://i.stack. ...

Service in Angular2+ that broadcasts notifications to multiple components and aggregates results for evaluation

My objective is to develop a service that, when invoked, triggers an event and waits for subscribers to return data. Once all subscribers have responded to the event, the component that initiated the service call can proceed with their feedback. I explore ...

I am looking to create buttons that can switch between two different styles of a specific element, like an h1 tag, when clicked. However, instead of toggling

//In this HTML document, I am trying to achieve a functionality where my buttons can toggle the style of an h1 element between the colors yellow and purple when clicked. However, I have encountered an issue where the buttons disappear during a transition ...

Are there alternative methods for inserting data into an array in JavaScript?

I'm having trouble with my code that is supposed to push data to an array variable, but instead I'm getting a blank array. Can someone help me figure out what I'm doing wrong? let users = [] // Here is where I'm looping through an aja ...

Learn the process of extracting data from dynamically generated elements in JavaScript

I am a beginner in Javascript and Jquery and have recently started exploring business rules with Chris Powers. https://github.com/chrisjpowers/business-rules My current project involves adding a range slider for numbers and a number spinner. I attempted us ...

Tips for sharing content within an iframe

Despite my efforts to find a solution, I have been unable to come across one that aligns with my specific situation. I currently have a form for inputting person data. Within this form, there is an iframe containing another form for adding relatives' ...

Sorting Vue.js properties based on object keys

Currently, I am dealing with a complex object that contains multiple network interfaces. Each interface is represented by a key-value pair in the object: https://i.stack.imgur.com/klkhH.png My goal is to create a Vue.js computed property that filters thi ...

Getting the user's name and country using `auth().createUserWithEmailAndPassword` is a simple process

Hey there fellow developers. I'm fairly new to react native and I'm trying to implement firebase authentication for a project. However, I'm stuck on how to include user name and country when using the standard auth().createUserWithEmailAndPa ...

Customize request / retrieve document cookies

I have successfully implemented a cookie in my express/node.js application. var express = require('express'); var cookieParser = require('cookie-parser') var app = express(); app.use(cookieParser()) app.use(function (req, res, next) ...

EmeraldSocks Tweenmax motion design

I need help with Tweenmax animation. I'm attempting to animate an id selector, but nothing is happening. Both the selector and content are unresponsive. Can someone assist me? Here is the code: <!DOCTYPE html> <html> <head> ...

Encountering a jQuery error while trying to utilize the $window.load

I have a code snippet that is functioning well when wrapped within a document ready event: jQuery(document).ready(function($) { $('tr[data-name="background_colour"] input.wp-color-picker').each(function() { //this section works fin ...

Utilizing encoding and decoding techniques in PHP and JavaScript with robust data attribute validation

I am utilizing data attributes to transfer information from HTML to JavaScript. The data attributes are derived from MySQL data, so they may contain spaces, resulting in validation errors since spaces are not permitted within attributes. My proposed solut ...

What is the best way to eliminate the left margin entirely in CSS?

I am attempting to create an image view that fully covers the window, without any margins. I have tried various solutions such as setting the body margin and padding to 0, but they do not seem to work. body { margin: 0px; padding: 0px; } or *, html { ...

Troubleshooting: Else block not functioning as expected within a React JS map function

I have a notification feature that makes an API call every 10 seconds to display an alert based on the response. However, I'm encountering an issue where the div is not being rendered properly. The div should be displayed based on certain conditions w ...

Extracting POST information through PHP's AJAX Request

I am facing an issue where I keep receiving null values when using the following code: Here is my Ajax request: formData = { u: "3959eeadb32e02b85a792e21c", id: "6d7613df26" }; $.ajax({ ...

The sinuous waveform in JavaScript

track : function(x, y, top, ampl) { return { top : top + 2, x : x + ampl * Math.sin(top / 20), y : (top / this.screenHeight < 0.65) ? y + 2 : 1 + y + ampl * Math.cos(top / 25) }; } This specif ...