Mixins
A big flaw of inheritance in the world of OOP is that it is limited to one level. This means you cannot extend more than a single class which can get messy quickly as you end up with large classes that have multiple responsibilities.
TypeScript has something called mixins. They act somewhat like traits in PHP, with the major difference being that under the hood they extend an object and return that. The result of that is rather than simply adding some methods, a completely new object is created that contains the old and new methods.
Mixins are a powerful tool to make use of composition over inheritance but they should be used with caution, as with everything, or you’ll end up with the same issues that come with the excessive use of inheritance.
Mixins Usage
1// Class we will extend through a mixin 2class Block {} 3 4// Function that serves as mixin 5function Timestamped<TBase extends Constructor>(Base: TBase) { 6 return class extends Base { 7 timestamp = new Date("2019-09-01"); 8 }; 9}10 11// Types12type AnyFunction<T = any> = (...input: any[]) => T;13type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>;14type TTimestamped = Mixin<typeof Timestamped>;15type MixinBlock = TTimestamped & Block;16 17// Register the Mixin18app19 .get<Services.Mixin.MixinService>(Container.Identifiers.MixinService)20 .set("timestamped", Timestamped);21 22// Apply the mixin23const block: MixinBlock = new (24 app25 .get<Services.Mixin.MixinService>(Container.Identifiers.MixinService)26 .apply<MixinBlock>("timestamped", Block)27)();28 29// Ensure the mixin did its job30console.log(block.timestamp === new Date("2019-09-01"));