Discovering a method to trigger a compile-time error is possible, but the approach may not be ideal due to its complexity. It might be better to opt for requiring a mixin or accept only a runtime test (triggered from the AbstractButton constructor), which would flag the issue very early on in the subclass development process.
I will explain how I achieved the compile-time error and why defining optional abstract methods in a certain way won't work as expected. The workaround involves setting up the base class without these optional methods and then ensuring that subclasses adhere to at least one of them.
abstract class AbstractButton {
// This method must always be implemented
abstract someRequiredMethod(): void;
}
Implementing this requirement solely using `class ___ extends AbstractButton` proved challenging. However, a strategy involving an empty function can generate a type error during compilation if the subclass doesn't implement one of the required methods.
... (remaining text remains unchanged)
Finally: Why do we check [Ctor] against [{ prototype: { ___ } }] instead of directly testing Ctor against { prototype: ____ }? To prevent the generic type argument from being distributed, which would disrupt the tests. Wrapping it in a tuple disables distribution.
In conclusion, although the elaborate method with mapped types serves its purpose, a simpler runtime check within the AbstractButton constructor could serve as a more straightforward alternative, catching issues early in subclass development.