Skip to main content

Naming conventions 3: improving naming quality

This article is Part 3 (the final part) of the three-part series on naming conventions. Building on the basics covered in Part 1: case conventions, variables, and constants and Part 2: Functions and Classes, it covers principles for improving naming quality, a comprehensive exercise, and an overall summary.

Use pronounceable, meaningful names

❌ Bad: Abbreviated, unpronounceable
// ❌ Bad: Abbreviated, unpronounceable
const genYmdhms = (): string => {
const now = new Date();
const pad = (n: number) => String(n).padStart(2, "0");
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;
};

const dfColor = "#fff";
const usrCnt = 10;

// ✅ Good: Pronounceable with clear meaning
const generateTimestamp = (): string => {
const now = new Date();
const pad = (n: number) => String(n).padStart(2, "0");
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;
};

const defaultColor = "#fff";
const userCount = 10;

Reasons:

  • Easier verbal communication with teammates
  • Easier to explain in code reviews
  • Easier for new members to understand

Use plural forms for arrays and lists

A variable that represents an array or list is recognizable as an array at a glance when it is plural.

❌ Bad: Singular
// ❌ Bad: Singular
const user = [{ id: 1 }, { id: 2 }];
const item = ["apple", "banana", "orange"];

user.forEach(u => console.log(u)); // Hard to tell that user is an array

// ✅ Good: Plural
const users = [{ id: 1 }, { id: 2 }];
const items = ["apple", "banana", "orange"];

users.forEach(user => console.log(user)); // Clear that users is the array and user is the element

// ✅ Use plural forms in TypeScript type definitions too
type User = {
id: number;
name: string;
};

type Users = User[];

Irregular plurals

✅ Good: Irregular English plurals
// ✅ Irregular English plurals
const children = [child1, child2]; // child → children
const people = [person1, person2]; // person → people
const mice = [mouse1, mouse2]; // mouse → mice

// ✅ Same singular and plural
const sheep = [sheep1, sheep2]; // sheep → sheep
const fish = [fish1, fish2]; // fish → fish

Unify words with the same meaning

Within a project, unify the words that represent the same concept.

❌ Bad: Different words for the same concept
// ❌ Bad: Different words for the same concept
class UserController {
getUser(id: string): User { }
}

class ProductController {
fetchProduct(id: string): Product { } // ❌ get and fetch are mixed
}

class OrderController {
retrieveOrder(id: string): Order { } // ❌ retrieve is mixed in too
}

// ✅ Good: Unified
class UserController {
getUser(id: string): User { }
}

class ProductController {
getProduct(id: string): Product { }
}

class OrderController {
getOrder(id: string): Order { }
}

// ────────────────────────────────────────────
// Other unification examples
// ────────────────────────────────────────────

// ❌ Bad: Multiple words for deletion
function removeUser(id: string) { }
function deleteProduct(id: string) { }
function eraseOrder(id: string) { }

// ✅ Good: Unified on delete
function deleteUser(id: string) { }
function deleteProduct(id: string) { }
function deleteOrder(id: string) { }

Common similar words

Examples of similar words to unify

MeaningCandidates
Retrieveget / fetch / retrieve
Deletedelete / remove / erase
Createcreate / make / build
Updateupdate / modify / edit
Sendsend / submit / post
Displayshow / display / render

Recommended approach: Create a glossary for your project and share it across the whole team.

✅ Good: A project terminology example (glossary.ts)
// ✅ A project terminology example (glossary.ts)
/**
* Project glossary
*
* - Retrieve data: get (fetch when asynchronous)
* - Create data: create
* - Update data: update
* - Delete data: delete
* - Display: show
*/

Use contrasting words

For values with opposite meanings, use names that form a contrast.

✅ Good: Examples of contrasting words
// ✅ Examples of contrasting words

// start ⇔ end
const startTime = new Date();
const endTime = new Date();

function startTimer() { }
function stopTimer() { } // ✅ start ⇔ stop

// min ⇔ max
const minValue = 0;
const maxValue = 100;

// previous ⇔ next
const previousPage = 1;
const nextPage = 3;

// first ⇔ last
const firstItem = items[0];
const lastItem = items[items.length - 1];

// open ⇔ close
function openModal() { }
function closeModal() { } // ✅ open ⇔ close

// show ⇔ hide
function showElement() { }
function hideElement() { } // ✅ show ⇔ hide

// enable ⇔ disable
function enableFeature() { }
function disableFeature() { } // ✅ enable ⇔ disable

// ❌ Bad: The contrast is unclear
function startProcess() { }
function endProcess() { } // ❌ Don't mix start and end for action functions

// ✅ Good
function startProcess() { }
function stopProcess() { } // ✅ start ⇔ stop

Use different pairs for points in time versus actions: for variables representing a point in time, startTimeendTime (start ⇔ end) is a natural pair. For functions representing an action, align them as startstop or beginend. The counterpart of startProcess is stopProcess.

Common contrasting words

List of contrasting words

Start / actionOpposite
startstop (end)
beginend (finish)
openclose
showhide
enabledisable
activatedeactivate
lockunlock
firstlast
minmax
previousnext
incrementdecrement
addremove
insertdelete
pushpop
acquirerelease

Avoid meaningless words

Generic words like Data, Info, and Manager provide no concrete information on their own. What you should avoid is a name made only of generic words, such as DataManager. When the thing being managed or described is clear, as in SessionManager or FileMetadata, there is no problem.

❌ Bad: Meaningless words
// ❌ Bad: Manager is too abstract (it's unclear what data it manages)
class DataManager {
processData() { }
}

// ✅ Good: Show the concrete responsibility
class UserRepository {
findById(id: string): User | null { }
save(user: User): void { }
}

// ────────────────────────────────────────────

// ❌ Bad: Object, Thing, and other abstractions
const userObject = { name: "Taro" };
const dataThing = [1, 2, 3];

// ✅ Good
const user = { name: "Taro" };
const numbers = [1, 2, 3];

There are exceptions, though

Some words carry meaning in specific contexts.

✅ Good: Acceptable examples
// ✅ Acceptable examples

// Metadata: the specific meaning of "data about data"
interface FileMetadata {
size: number;
createdAt: Date;
mimeType: string;
}

// Config/Settings: a conventional name representing configuration
interface AppConfig {
apiUrl: string;
timeout: number;
}

// Context: a convention in frameworks such as React/Angular
const UserContext = React.createContext<User | null>(null);

Abbreviating variable names

Use abbreviations only when they are generally recognized.

✅ Good: Generally recognized abbreviations
// ────────────────────────────────────────────
// ✅ Generally recognized abbreviations
// ────────────────────────────────────────────

// ID (identifier)
const userId = "12345";
const productId = 100;

// URL (Uniform Resource Locator)
const apiUrl = "https://api.example.com";

// HTTP (HyperText Transfer Protocol)
const httpClient = new HttpClient();

// API (Application Programming Interface)
const apiResponse = await fetchData();

// DB (Database)
const dbConnection = createConnection();

// Auth (Authentication)
const authToken = "abc123";

// Config (Configuration)
const appConfig = loadConfig();

// Temp (Temporary)
const tempValue = calculateTemp();

// Max/Min (Maximum/Minimum)
const maxRetries = 3;
const minValue = 0;

// Prev/Next (Previous/Next)
const prevPage = 1;
const nextPage = 3;

// ────────────────────────────────────────────
// ❌ Abbreviations to avoid
// ────────────────────────────────────────────

// ❌ Custom abbreviations
const usrNm = "Taro"; // ✅ userName
const prdLst = []; // ✅ productList
const calcTtl = () => {}; // ✅ calculateTotal

// ❌ Just dropping vowels
const btn = document.querySelector('button'); // ✅ button
const msg = "Hello"; // ✅ message
const err = new Error(); // ✅ error (err is sometimes acceptable)

// ❌ Abbreviations that make no sense without context
const d = new Date(); // ✅ date or currentDate
const i = 0; // ✅ index or count (outside of loops)
const tmp = getValue(); // ✅ temporary or a concrete name

Abbreviating loop variables is acceptable

✅ Good: Conventional abbreviations are acceptable in loops
// ✅ Conventional abbreviations are acceptable in loops
for (let i = 0; i < 10; i++) {
console.log(i);
}

// ✅ Nested loops
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
matrix[i][j] = 0;
}
}

// ✅ When a more meaningful name is preferable
for (let userIndex = 0; userIndex < users.length; userIndex++) {
const user = users[userIndex];
// ...
}

// ✅ Use full names with forEach/map
users.forEach(user => { // ✅ user (not u)
console.log(user.name);
});

Exercise 5: A comprehensive naming exercise

Fix the following code to follow the naming conventions for clean code.

❌ Bad: Before
// ❌ Before

const d = new Date();
const usrCnt = 100;

interface prdData {
id: number;
nm: string;
prc: number;
}

class usrMgr {
getUsrInf(id: number) {
// ...
}

delUsr(id: number) {
// ...
}
}

function calcTtl(items: any[]) {
let t = 0;
for (let i = 0; i < items.length; i++) {
t += items[i].prc;
}
return t;
}

const isNotComplete = false;
if (!isNotComplete) {
// ...
}
📝 View answer
✅ Good: After
// ✅ After

const currentDate = new Date();
const userCount = 100;

interface ProductData {
id: number;
name: string;
price: number;
}

class UserManager {
getUser(id: number) {
// ...
}

deleteUser(id: number): void {
// ...
}
}

function calculateTotal(items: ProductData[]): number {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
return total;
}

// Avoid negative forms
const isComplete = true;
if (isComplete) {
// ...
}

calculateTotal also has an alternative using reduce.

✅ Good: Alternative (using reduce)
function calculateTotal(items: ProductData[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}

Key fixes:

  1. dcurrentDate: clarify the meaning
  2. usrCntuserCount: avoid abbreviation
  3. prdDataProductData: PascalCase
  4. nmname, prcprice: full words
  5. usrMgrUserManager: PascalCase
  6. getUsrInfgetUser: use full words and remove the redundant "Info"
  7. delUsrdeleteUser: full word + unified verb
  8. calcTtlcalculateTotal: full words
  9. ttotal: a meaningful name
  10. isNotCompleteisComplete: avoid the negative form

Summary of naming conventions

Naming conventions quick reference

TargetRuleExample
VariablecamelCaseuserName, itemCount
ConstantUPPER_SNAKE_CASEMAX_COUNT
FunctioncamelCasegetUserById
ClassPascalCaseUserService
InterfacePascalCaseUserProfile
Type aliasPascalCaseUserId
EnumPascalCaseUserRole
Booleanis / has / can / should + state/abilityisValid, canEdit
ArrayPluralusers, items
Naming principles
  • Use names with clear intent
  • Use searchable names
  • Maintain consistency
  • Reduce the reader's cognitive load

  • Comments — the idea of leaving only what code cannot express in comments
  • Variables — handling variables, which together with naming supports readability