| name | clean-names |
| description | Use when naming, renaming, or fixing names of variables, functions, classes, interfaces, or modules in TypeScript. Enforces Clean Code principles—descriptive names, appropriate length, no encodings. |
| when_to_use | Also trigger on: single-letter or cryptic identifiers (`d`, `x`, `proc`), Hungarian notation (`strName`, `arrUsers`, `nCount`), `I`-prefixed interfaces (`IUserRepository`), function names that hide side effects (e.g. `getConfig` that also mutates state), ambiguous names like `rename(source, target)`, or asks like "rename this", "clearer name".
|
Clean Names
N1: Choose Descriptive Names
Names should reveal intent. If a name requires a comment, it doesn't reveal its intent.
const d = 86400;
const SECONDS_PER_DAY = 86400;
function proc(values: number[]) {
return values.filter((value) => value > 0);
}
function filterPositiveNumbers(numbers: number[]) {
return numbers.filter((number) => number > 0);
}
N2: Choose Names at the Appropriate Level of Abstraction
Don't pick names that communicate implementation; choose names that reflect the level of abstraction of the class or function.
function getMapOfUserIdsToNames() {
}
function getUserDirectory() {
}
N3: Use Standard Nomenclature Where Possible
Use terms from the domain, design patterns, or well-known conventions.
class UserFactory {
create(data: unknown) {
}
}
function calculateAmortization(principal: number, rate: number, term: number) {
}
N4: Unambiguous Names
Choose names that make the workings of a function or variable unambiguous.
function rename(source: string, target: string) {
}
function renameFile(oldPath: string, newPath: string) {
}
N5: Use Longer Names for Longer Scopes
Short names are fine for tiny scopes. Longer scopes need longer, more descriptive names.
const total = numbers.reduce((sum, n) => sum + n, 0);
const MAX_RETRY_ATTEMPTS_BEFORE_FAILURE = 5;
const MAX = 5;
N6: Avoid Encodings
Don't encode type or scope information into names. Modern editors make this unnecessary.
const strName = "Alice";
const arrUsers: string[] = [];
const nCount = 0;
const name = "Alice";
const users: string[] = [];
const count = 0;
interface IUserRepository {
findById(id: string): Promise<unknown>;
}
interface UserRepository {
findById(id: string): Promise<unknown>;
}
N7: Names Should Describe Side Effects
If a function does something beyond what its name suggests, the name is misleading.
const configStore = new Map<string, string>();
function getConfig(configPath: string) {
if (!configStore.has(configPath)) {
configStore.set(configPath, "{}");
}
return JSON.parse(configStore.get(configPath) ?? "{}");
}
function getOrCreateConfig(configPath: string) {
if (!configStore.has(configPath)) {
configStore.set(configPath, "{}");
}
return JSON.parse(configStore.get(configPath) ?? "{}");
}
Quick Reference
| Rule | Principle | Example |
|---|
| N1 | Descriptive names | SECONDS_PER_DAY not d |
| N2 | Right abstraction level | getUserDirectory() not getMapOf... |
| N3 | Standard nomenclature | UserFactory, calculateAmortization |
| N4 | Unambiguous | renameFile(oldPath, newPath) |
| N5 | Length matches scope | Short for loops, long for globals |
| N6 | No encodings | users not arrUsers |
| N7 | Describe side effects | getOrCreateConfig() |