ESLint TypeScript Rule Utilities
eslint-etc provides a collection of utility functions designed primarily to aid in the implementation and testing of custom ESLint rules, particularly those targeting TypeScript codebases. The current stable version is 5.2.1. While there isn't a stated release cadence, updates are typically made as needed for new features, bug fixes, or compatibility with newer ESLint and TypeScript versions. A key differentiator is the `fromFixture` utility, which enables a TSLint-like fixture testing approach for ESLint rules. This simplifies the creation of test cases by allowing developers to directly annotate expected error locations and messages within multiline code strings, abstracting away the need for explicit line and column numbers. This library is largely used by its author for their own suite of ESLint rules, indicating a practical, developer-focused design, though documentation can be light for external users.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'program') (or similar for 'getTypeChecker')
cause An ESLint rule is attempting to access TypeScript parser services (e.g., `parserServices.program` or `parserServices.getTypeChecker`) but `@typescript-eslint/parser` is not correctly configured, or the file being linted is not recognized as a TypeScript file.fixEnsure your ESLint configuration includes `parser: '@typescript-eslint/parser'` and, for type-aware rules, `parserOptions.project` is correctly set to point to your `tsconfig.json` file. -
ReferenceError: fromFixture is not defined (or similar for other exports)
cause `fromFixture` (or another utility from `eslint-etc`) was used in a test file without being properly imported.fixAdd `import { fromFixture } from 'eslint-etc';` (or the relevant symbol) to the top of your test file to ensure the utility is available.
Warnings
- breaking Major version increments (e.g., v3.0.0, v4.0.0, v5.0.0) in `eslint-etc` often introduce breaking changes due to updates in peer dependencies like ESLint or TypeScript, or internal API refactors.
- gotcha The documentation for `eslint-etc` is noted by its author as 'light', primarily serving the author's own use cases for implementing ESLint rules.
Install
-
npm install eslint-etc -
yarn add eslint-etc -
pnpm add eslint-etc
Imports
- fromFixture
const { fromFixture } = require('eslint-etc')import { fromFixture } from 'eslint-etc' - getParserServices
const { getParserServices } = require('eslint-etc')import { getParserServices } from 'eslint-etc' - isIdentifier
const { isIdentifier } = require('eslint-etc')import { isIdentifier } from 'eslint-etc'
Quickstart
import { RuleTester } from '@typescript-eslint/rule-tester';
import { fromFixture } from 'eslint-etc';
import { stripIndent } from 'common-tags'; // Often used for multiline strings in tests
// Define a simple mock ESLint rule
const noConstRule = {
meta: {
type: 'suggestion',
messages: {
noConst: 'Do not use `const` for variable declarations.',
},
schema: [],
},
create(context) {
return {
VariableDeclaration(node) {
if (node.kind === 'const') {
context.report({
node,
messageId: 'noConst',
});
}
},
};
},
};
const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
// Ensure tsconfig.json is properly configured for type-aware rules
project: './tsconfig.json',
},
});
ruleTester.run('no-const-rule', noConstRule as any, {
valid: [
{ code: 'let name = "alice";' },
{ code: 'var age = 30;' },
],
invalid: [
fromFixture(stripIndent`
const name = "alice";
~~~~~ [noConst]
`),
fromFixture(stripIndent`
const role = 'cto';
~~~~~ [noConst]
let value = 10;
`),
fromFixture(stripIndent`
const x = 1;
~~~~~ [noConst]
const y = 2;
~~~~~ [noConst]
`)
],
});