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.


Before we start we need to establish what a few recurring variables and imports in this document refer to when they are used.

1import { app } from "@arkecosystem/core-kernel";
  • The app import refers to the application instance which grants access to the container, configurations, system information and more.

Mixins Usage

1import { app } from "@arkecosystem/core-kernel";
3// Class we will extend through a mixin
4class Block {}
6// Function that serves as mixin
7function Timestamped<TBase extends Constructor>(Base: TBase) {
8 return class extends Base {
9 timestamp = new Date("2019-09-01");
10 };
13// Types
14type AnyFunction<T = any> = (...input: any[]) => T;
15type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>;
16type TTimestamped = Mixin<typeof Timestamped>;
17type MixinBlock = TTimestamped & Block;
19// Register the Mixin
21 .get<Services.Mixin.MixinService>(Container.Identifiers.MixinService)
22 .set("timestamped", Timestamped);
24// Apply the mixin
25const block: MixinBlock = new (
26 app
27 .get<Services.Mixin.MixinService>(Container.Identifiers.MixinService)
28 .apply<MixinBlock>("timestamped", Block)
31// Ensure the mixin did its job
32console.log(block.timestamp === new Date("2019-09-01"));
Last updated 2 years ago
Edit Page