A selector parameter is a boolean parameter that’s used to determine which of two paths to take through a method. Specifying such a
parameter may seem innocuous, particularly if it’s well-named.
Unfortunately, developers calling the method won’t see the parameter name, only its value. They’ll be forced either to guess at the meaning or to take extra time to look the method up. Additionally, selector parameters create maintenance challenges: adding a third option requires changing the boolean to an enum or similar type, breaking existing code.
This rule finds methods with a boolean that is used to determine which path to take through the method.
function feed(name: string, isHuman: boolean) {
if (isHuman) {
// implementation for human
} else {
// implementation for animal
}
}
// Intent is not clear at call site
feed('Max', false); // does this mean not to feed Max?
Instead, split the method into separate, clearly named methods:
function feedHuman(name: string) {
offerSushi(name);
}
function feedAnimal(name: string) {
offerCarrot(name);
}
// Clear intent at call site
feedHuman("Joe");
feedAnimal("Max");
Alternatively, use descriptive object parameters or types:
type EntityType = 'human' | 'animal';
function feed(name: string, entityType: EntityType) {
if (entityType === 'human') {
// implementation for human
} else {
// implementation for animal
}
}
feed('Max', 'animal');
function feed(name: string, { human = true } ) {
if (human) {
// implementation for human
} else {
// implementation for animal
}
}
feed('Max', { human: false });