# core/quality/eslint/no-boolean-trap.eslint.rule.ts

> 43 lines of code and 7 definitions.

Tree: GovLab Quality
Language: typescript
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-quality-eslint-no-boolean-trap-eslint-rule-ts
Source text: https://banes-lab.com/source/quality/core/quality/eslint/no-boolean-trap.eslint.rule.ts.txt

Listed in [core/quality/eslint](https://banes-lab.com/api/source/quality/core/quality/eslint.md), after [core/quality/eslint/no-bitwise-outside-flags.eslint.rule.ts](https://banes-lab.com/source/quality/core/quality/eslint/no-bitwise-outside-flags.eslint.rule.ts.md) and before [core/quality/eslint/no-call-enumeration.eslint.rule.ts](https://banes-lab.com/source/quality/core/quality/eslint/no-call-enumeration.eslint.rule.ts.md).

## Definitions

- `isBooleanLiteral` (lexical_declaration, line 6)
- `booleanLiteralCount` (lexical_declaration, line 10)
- `MIN_BOOL_TRAP` (lexical_declaration, line 4)
- `create` (method_definition, line 21, exported)
- `check` (lexical_declaration, line 22, exported)
- `count` (lexical_declaration, line 26, exported)
- `handlers` (lexical_declaration, line 31, exported)

## Contained in

- [core/quality/eslint](https://banes-lab.com/anatomy/quality/folder-quality-core-quality-eslint.md)

## Linked from

- [core/quality/eslint](https://banes-lab.com/anatomy/quality/folder-quality-core-quality-eslint.md)

## Source

```typescript
import type { Rule } from "eslint";
import { govlabMeta } from "#core/factories/eslint.factory";

const MIN_BOOL_TRAP = 2;

const isBooleanLiteral = function isBooleanLiteral(arg: { type: string; value?: unknown }): boolean {
    return arg.type === "Literal" && typeof arg.value === "boolean";
};

const booleanLiteralCount = function booleanLiteralCount(args: { type: string; value?: unknown }[]): number {
    let count = 0;
    for (const arg of args) {
        if (isBooleanLiteral(arg)) {
            count += 1;
        }
    }
    return count;
};

export default {
    create(context: Rule.RuleContext): Rule.RuleListener {
        const check = (node: Rule.Node): void => {
            if (node.type !== "CallExpression" && node.type !== "NewExpression") {
                return;
            }
            const count = booleanLiteralCount(node.arguments);
            if (count >= MIN_BOOL_TRAP) {
                context.report({ data: { count: String(count) }, messageId: "booleanTrap", node });
            }
        };
        const handlers: [string, (node: Rule.Node) => void][] = [
            ["CallExpression", check],
            ["NewExpression", check],
        ];
        return Object.fromEntries(handlers);
    },
    meta: govlabMeta({
        canonical: ["boolean-trap"],
        description:
            "Disallow a call or construction passing two or more boolean literal arguments — mandate a named options object",
        messages: {
            booleanTrap:
                "This passes {{count}} boolean literals positionally — a boolean trap: the call site cannot say what each flag means, and adding a flag shifts every position. Pass a single named options object ({ active: true, archived: false }) so each intent is labeled where it is set.",
        },
        ruleId: "boolean_trap",
    }),
} satisfies Rule.RuleModule;
```
