Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ESLint plugin or rule for preventing generic variable names?

I've been searching for an eslint plugin that gives errors on generic variable/parameter/function names. I only find rather tedious answers (listing every possible symbol without pattern matching) or answers that have to do with naming styles (eg camel case). That's not what I am looking for.

Some example "too generic" identfiers/names:

  • query, result, and queryResult
  • data, data1, _data1, _getData(), _getDataInfo()
  • var, info, tmp
  • metadataInfo, meta, data, info
  • thing, whatever, boo, foo, blah, a, b
  • input, param, arg
  • response, total, ...
  • calculateBasePay(input)

Some examples of prefixes and other words that are fine, unless used with a generic variable.

  • get - getData
  • set - setInfo
  • create, translate, manipulate, manage
  • statusObject = budget.getStatusObject // not OK
    • approvalStatus = budget.getApprovalStatus // OK

some examples of what might add complexity:

  • pluralization, especially with words that have odd pluralizations like 'thingy/thingies'
  • my own code (more strict) vs library parameters, properties, and objects (lets it go)
  • combining generic names eg. 'metaDataResponseInfo'
  • preventing abbreviations (requires a dictionary)

Anyway... I have a half-baked solution I will post as a potential answer, but I am interested in alternatives.

like image 736
Kimball Robinson Avatar asked Dec 09 '25 08:12

Kimball Robinson


1 Answers

Here's my partial solution. Hopefully there's a better one out there.

Inside eslintrc.js

const genericVariableNames = [
  'arg', 'args', 'argument', 'count', 'counter', 'data', 'err', 'error',
  'flag', 'foo', 'idx', 'index', 'info', 'information', 'item', 'key', 'message', 'meta', 'metadata',
  'output', 'param', 'parameter', 'queries', 'query', 'record', 'result', 'status', 'stuff', 'junk',
  'tmp', 'temp', 'temporary|temporaries', 'thing', 'thingy', 'thingies',
  'val', 'value', 'var', 'variable',
]
const genericPrefixes = [ // these prefixes are fine, as long as a generic variable name isn't next.
  'get', 'set', 'create', 'update', 'my', 'this', '_',
]
const genericVariableNamesPattern =
    '(' + genericPrefixes.join('|') + ')?' + // optional prefix, prevents identifiers like 'getVar' without forbidding 'get'
    '(' +
    genericVariableNames.join('|') +
    '(e?s)?' + // handle -es and -s plurals.  Doesn't handle -ies plurals.
    '\\d*' + // adding numbers won't make an identifier better, eg. tmp1, status2, etc.
    ')+' // Require AT LEAST ONE generic symbol; prevent chained generic names: tmpVar, resultVariable, argumentCounterVar;
const identifierWithGenericName = `Identifier[name=/^${genericVariableNamesPattern}$/i]`
const clarityGuidance = 'Names should be helpful even out of context (search-results/pasted/stacktrace/glimpse...)'

// ... inside the rules object...

'no-restricted-syntax': [
  'error',
  {
     selector: `FunctionDeclaration ${identifierWithGenericName}`,
     message: `Generic function names and parameters are not allowed.  ${clarityGuidance}`,
   },
   {
     selector: `VariableDeclarator > ${identifierWithGenericName}`,
     message: `Generic variable names are not allowed.  ${clarityGuidance}`,
   },
   {
     selector: `ArrowFunctionExpression > AssignmentPattern > ${identifierWithGenericName}`,
     message: `Generic arrow function parameter names are not allowed.  ${clarityGuidance}`,
   },
 ],
like image 192
Kimball Robinson Avatar answered Dec 12 '25 14:12

Kimball Robinson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!