Zachary W. Huang
Idea: we can wrap an object transparently in order to add behaviors/functionality dynamically.
abstract class Component {
  abstract doThing(): void;
}
class ComponentA extends Component {
  doThing() {
    console.log("A")
  };
}
class Decorator implements Component {
  component: Component;
  constructor(component: Component) {
    this.component = component;
  }
  doThing() {
    console.log("Before");
    this.component.doThing();
    console.log("After");
  };
}
function main() {
  const component = new ComponentA();
  const decoratedComponent = new Decorator(component);
  decoratedComponent.doThing(); // "Before  A  After"
}