Empty subclasses that exist only to encode a type code — `class Female extends Person {}` and `class Male extends Person {}` with no overridden behavior.
A subclass whose only purpose was to encode a type code or add nothing collapses back into a field on the parent.
Before the refactoring
class Person {}class Female extends Person {}class Male extends Person {}
After the refactoring
class Person {constructor(gender) { this.gender = gender; }}
Every new variant is a new file; the hierarchy adds ceremony without behavior; consumers may type-test the subclass instead of treating it as data.
Removing a subclass referenced by name elsewhere (factories, registries) breaks those references — confirm no consumer is type-testing the subclass.
Smaller hierarchy; new variants are field values instead of new files; the parent regains its variability point as data.
Removing subclasses referenced by name elsewhere — factories, registries, type-tests in legacy code — breaks those references silently.