@pegasusheavy/eslint-typescript-access
v1.0.0
Published
ESLint plugin that enforces explicit access modifiers on TypeScript class members
Maintainers
Readme
@pegasusheavy/eslint-typescript-access
An ESLint plugin that enforces explicit access modifiers and accessibility ordering on TypeScript class members.
Features
- Explicit Access Modifiers — Require
public,protected, orprivateon all class members - Accessibility Ordering — Enforce member ordering by visibility (public → protected → private)
- Highly Configurable — Customize rules per member type (methods, properties, constructors, etc.)
- ESLint 9 Flat Config — Built for modern ESLint with first-class flat config support
Installation
pnpm add -D @pegasusheavy/eslint-typescript-accessnpm install -D @pegasusheavy/eslint-typescript-accessyarn add -D @pegasusheavy/eslint-typescript-accessUsage
Flat Config (ESLint 9+)
// eslint.config.js
import tsAccessPlugin from "@pegasusheavy/eslint-typescript-access";
export default [
{
plugins: {
"@pegasusheavy/typescript-access": tsAccessPlugin,
},
rules: {
"@pegasusheavy/typescript-access/explicit-member-accessibility": "error",
"@pegasusheavy/typescript-access/member-accessibility-order": "error",
},
},
];Using Presets
The plugin provides two presets:
// eslint.config.js
import tsAccessPlugin from "@pegasusheavy/eslint-typescript-access";
export default [
// Recommended: enables both rules with sensible defaults
tsAccessPlugin.configs.recommended,
// Or Strict: more explicit configuration
tsAccessPlugin.configs.strict,
];Rules
explicit-member-accessibility
Requires explicit accessibility modifiers on class properties and methods.
Options
{
// Base accessibility requirement for all members
// "explicit" - require public/protected/private
// "no-public" - disallow explicit public (use implicit)
// "off" - disable the rule
accessibility: "explicit",
// Override for specific member types
overrides: {
constructors: "explicit",
methods: "explicit",
properties: "explicit",
parameterProperties: "explicit",
accessors: "explicit",
}
}Examples
// ❌ Invalid (missing accessibility)
class Example {
name: string;
getName() {
return this.name;
}
}
// ✅ Valid
class Example {
public name: string;
public getName() {
return this.name;
}
}member-accessibility-order
Enforces that class members are ordered by accessibility level.
Options
{
// Order of accessibility levels (first = top of class)
order: ["public", "protected", "private"],
// If true, ordering is checked within each member kind separately
// (fields, methods, accessors, etc.)
groupByKind: false
}Examples
// ❌ Invalid (private before public)
class Example {
private secret: string;
public name: string;
}
// ✅ Valid (public → protected → private)
class Example {
public name: string;
protected id: number;
private secret: string;
}Custom Ordering
You can customize the order to match your team's preferences:
// Private first
{
"@pegasusheavy/typescript-access/member-accessibility-order": [
"error",
{ order: ["private", "protected", "public"] }
]
}Group By Kind
With groupByKind: true, ordering is checked within each member type separately, allowing you to group fields together, methods together, etc:
// ✅ Valid with groupByKind: true
class Example {
private field1: string;
public field2: string; // OK - different group than methods below
private method1() {}
public method2() {} // Error - within methods, public should come first
}Preset Configurations
recommended
{
"@pegasusheavy/typescript-access/explicit-member-accessibility": "error",
"@pegasusheavy/typescript-access/member-accessibility-order": "error"
}strict
{
"@pegasusheavy/typescript-access/explicit-member-accessibility": ["error", {
accessibility: "explicit",
overrides: {
constructors: "explicit",
methods: "explicit",
properties: "explicit",
parameterProperties: "explicit",
accessors: "explicit"
}
}],
"@pegasusheavy/typescript-access/member-accessibility-order": ["error", {
order: ["public", "protected", "private"],
groupByKind: false
}]
}Why Use This Plugin?
Explicit is Better Than Implicit
TypeScript defaults class members to public when no modifier is specified. This can lead to:
- Ambiguity — Is a member public intentionally or by accident?
- API Surface Creep — Private implementation details accidentally exposed
- Code Review Friction — Reviewers can't tell intent without checking context
By requiring explicit modifiers, your code becomes self-documenting:
// Intent is clear
class UserService {
public getCurrentUser() {} // Part of public API
protected validateUser() {} // For subclasses
private cache: Map<string, User>; // Implementation detail
}Consistent Ordering
Enforcing accessibility order makes classes easier to navigate:
- Public API First — Consumers see the interface immediately
- Protected Next — Subclass authors find extension points
- Private Last — Implementation details at the bottom
License
MIT © Pegasus Heavy Industries LLC
