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

differences in opinion between JavaScript code and browser add-ons/extensions

As the owner and developer of an e-commerce website, I find that potential customers often contact us regarding ordering issues. Upon investigation, we consistently discover that the problem is caused by JavaScript errors. We frequently check their browse ...

Exploring the Power of Pythons, Selenium, and XPATH for Handling New Windows

Is it possible to retrieve an element through XPath after using the .click() method when that element is located within a section of JavaScript known as BODY_BLOCK_JQUERY_REFLOW and appears only after the click action? I am attempting to access this speci ...

NextJS: Build error - TypeScript package not detected

I'm facing an issue while setting up my NextJS application in TypeScript on my hosting server. On my local machine, everything works fine when I run next build. However, on the server, I'm encountering this error: > next build It seems that T ...

Guide on implementing factory updates to the display

I am attempting to update a reference within my factory in an asynchronous fashion, but I am not seeing the changes reflected in my view. View <div ng-repeat="Message in Current.Messages">{{Message.text}}</div> Controller angular.module(&ap ...

Creating a dynamic visual experience with Angular 2: How to implement multiple font colors

I have a text area which is connected to one string, with the default text color set to white. <textarea style="background-color: black;color:#fff;" [(ngModel)]="outputText"></textarea> The connected string contains multiple variables. retur ...

The image will come to life with animation as the background position is adjusted using Skrollr

Trying to create a div that switches the background image every X pixels scrolled. Initially experimented with changing the background-image, including using sprites and adjusting background position, but encountered a distracting "flickering" effect. Exa ...

What could be causing the malfunction in this JavaScript and WebRTC code?

<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Vid Chat App</title> </head> <body> <video controls autoplay> </video> <script src="https: ...

What is preventing me from retrieving the parameter in the controller?

I could use some assistance with implementing pagination for displaying data. However, I am encountering issues in retrieving the parameter in the Controller Method. To provide more context, I have created a demo on CodePen which can be viewed at http://c ...

Is there a jQuery function that can produce repeated output and append content with each successive click?

Attempting to implement a dynamic searchbar with various parameters has led me to explore using jQuery to load and clone the searchbar file in order to append it to the body dynamically. I have made several attempts to modify selectors without achieving t ...

Error: Call stack size limit reached in Template Literal Type

I encountered an error that says: ERROR in RangeError: Maximum call stack size exceeded at getResolvedBaseConstraint (/project/node_modules/typescript/lib/typescript.js:53262:43) at getBaseConstraintOfType (/project/node_modules/typescript/lib/type ...

The Javascript code is failing to run following an ajax request

When I use XMLHttpRequest.send to call a php script that contains some javascript code, the javasript in the called php script does not run. The process of making the call: var formdata = new FormData(); formdata.append("uploadfilename", file); var ajax ...

React Material UI unselect

I have been exploring a MUI select field implementation using this example as a guide. While I was able to make the code work, there are a few issues that I encountered. One of them is the inability to deselect a value once it has been selected. Additional ...

Managing enum types with json2typescript

After receiving a JSON response from the back-end that includes an Enum type, I need to deserialize it. The JSON looks like this: { ..., pst:['SMS','EMAIL'], ... } In Typescript, I have defined my enum class as follows: export enum Pos ...

At what point is the rendering process of ng-switch completed?

I am currently utilizing ui-router and facing a challenge in instantiating a widget that requires a DOM element specified by its id as a parameter. The specific DOM element is nested within a <div ng-switch>, and I need to ensure the widget construct ...

Creating dropdown menus dynamically and populating them based on the selection made in one dropdown menu to determine the options available

Looking to enhance the filtering options in my ngGrid, I stumbled upon the concept of Filtering in Ignite UI grid and was impressed by its functionality. I am now attempting to implement a similar feature in AngularJS. Breaking down the task into 4 compon ...

The issue with AngularJS Routing is that it fails to refresh the menu items when the URL and views are being

My current project involves implementing token-based authentication using the MEAN stack. The goal of my application is to display different menu items based on whether a user is logged in or not. When there is no token present, the menu should show option ...

Tips for stopping webpack from creating compiled files in the source directory

I'm in the process of transitioning my AngularJs project from ES6 to TypeScript and I've integrated webpack with ts-loader. However, I've encountered an issue where the compiled files and source maps are saved in my directory instead of bei ...

Tips for creating a responsive Livewire Pagination system

Looking to make Livewire pagination responsive? When using Bootstrap, simply add flex-wrap to the pagination class to ensure responsiveness. Component: class Index extends Component { use WithPagination; protected $paginationTheme = 'bootstr ...

Preventing the use of double-click on Grooveshark

I am currently in the process of creating a webpage to serve as a jukebox for parties. My goal is to have the page load Grooveshark with a transparent overlay (or any other necessary method) that can prevent users from forcefully adding their song to the f ...

Display buttons when hovering with React

Seeking assistance with implementing functionality in a React application where buttons for editing and deleting display only when the mouse hovers over the corresponding row. Currently, the implemented code displays these buttons in all rows on hover. Sn ...