How to prevent a class from being inherited from in TypeScript.
TypeScript lacks the final
class modifier common in other languages, but with the use of a decorator we can achieve similar functionality.
Final class decorator
export function final<T extends { new (...args: any[]): object }>(target: T): T {
return class Final extends target {
constructor(...args: any[]) {
if (new.target !== Final) {
throw new Error('Cannot inherit from final class');
}
super(...args);
}
};
}
Usage:
@final
export class Example {
}
An exception will be thrown if you try to inherit from Example
and create a new instance of that class.
export class ExampleSub extends Example {
}
new ExampleSub(); // error is thrown
This exception will only happen at runtime, so keep that in mind.
Frozen class decorator
JavaScript also has the concept of freezing an object, which basically means that the object becomes immutable.
export function frozen(target: Function): void {
Object.freeze(target);
Object.freeze(target.prototype);
}
With this decorator you can prevent the class itself and its prototype from being changed.
Usage:
@frozen
export class Example {
}
const isFrozen = Object.isFrozen(Example); // true
Conclusion
You can combine these two together and prevent a class from being modified and inherited from.
You can find the source code in this gist.