Skip to content
Knowledge Hub

Six naming rules and how to apply them in TypeScript and NestJS Basic

Estimated reading time: 6 min read

This page answers: which general rules apply to every name, and how to apply them concretely in TypeScript and NestJS code.

Loading diagram…

The reader needs to know what this value is and what it is for, not how it was computed.

// Before
const d = 30;
const list2 = orders.filter((o) => o.s === 3);
// After
const refundWindowDays = 30;
const shippedOrders = orders.filter((order) => order.status === OrderStatus.SHIPPED);

Single-letter names are only acceptable for very short-lived variables (Google TS Style Guide: a scope of 10 lines or fewer), like i in a loop.

If a codebase has getUser, fetchUser, loadUser and retrieveUser, readers will assume they differ. Give each verb a meaning and keep it across every module:

Verb Meaning in the team When there is no result
find... Query, may find nothing Return null / empty array
get... Must exist Throw (NotFoundException)
fetch... Network call (HTTP, another service) Depends, but always with a timeout
list... Returns a paginated list Empty array
create / update / delete Writes Use consistently, do not mix with add / remove / insert

This table is one choice, not a standard. Its value lies in the whole team using the same table.

data, info, item, obj, manager, helper, utils, handle, process fit anything, so they say nothing. They are also code magnets: after two years utils.ts becomes a 3,000-line dumping ground.

// Before
class OrderManager { handle(data: any) { /* ... */ } }
// utils.ts: formatMoney, retry, parseJwt, slugify...
// After
class OrderCancellationService { cancel(command: CancelOrderCommand) { /* ... */ } }
// money-format.ts, retry-with-backoff.ts, jwt-claims.ts

Review tip: if you cannot give a class a specific name, it is usually doing two things. Split it first and the names will appear.

4. Booleans are yes/no questions, not negations

Section titled “4. Booleans are yes/no questions, not negations”

Use the prefixes is, has, can, should so they read like questions. Avoid negated names: !isNotActive forces the brain to flip twice.

// Before
if (!user.notVerified && !disableRetry) { ... }
// After
if (user.isVerified && shouldRetry) { ... }

For API fields there is the opposite view: Google AIP-140 recommends dropping is (disabled rather than is_disabled). Pick one rule for the JSON contract and stick to it.

Is timeout = 30 30 seconds or 30 milliseconds? The value looks plausible either way, so the resulting incident is very hard to find.

// Before
const timeout = 30;
const maxSize = 10;
// After
const timeoutMs = 30_000;
const maxUploadSizeBytes = 10 * 1024 * 1024;

When possible, push the unit into the type (e.g. a Duration type). As long as it is a number, the unit must be in the name: Ms, Seconds, Bytes, Cents. AIP-140 also recommends familiar unit abbreviations in field names, such as distance_km.

6. No type prefixes, no home-made abbreviations

Section titled “6. No type prefixes, no home-made abbreviations”

TypeScript already has the type; do not repeat it in the name. The Google TS Style Guide forbids Hungarian notation and abbreviations made by dropping letters inside a word (e.g. cstmrId).

Avoid Use Reason
strName, arrOrders, bIsPaid name, orders, isPaid The type already says it
IOrderRepository OrderRepository The style guide does not mark interfaces
_balance for private private balance Use the modifier, not _
cstmr, qty, amt, usrCfg customer, quantity, amount, userConfig Home-made abbreviations make grep fail
loadHTTPURL, userID loadHttpUrl, userId Treat abbreviations as words

Abbreviations everyone knows are fine: id, url, http, db, config, api.

TypeScript: follow the Google TS Style Guide

Section titled “TypeScript: follow the Google TS Style Guide”

The Google TypeScript Style Guide is a public, complete standard with a reason for each rule. The points that come up most in review:

  • UpperCamelCase for classes, interfaces, types, enums, decorators, type parameters.
  • lowerCamelCase for variables, parameters, functions, methods, properties.
  • CONSTANT_CASE only for module-level constants, module-level static fields and enum values. A const inside a function is still lowerCamelCase.
  • No I prefix for interfaces, no _ prefix/suffix for private members.
  • Abbreviations are treated as words: loadHttpUrl, not loadHTTPURL.
// Before
const Max_Retry = 3;
interface IPaymentGateway { ChargeCard(amt: number): Promise<any>; }
class paymentService { private _gw: IPaymentGateway; }
// After
const MAX_RETRY_ATTEMPTS = 3;
interface PaymentGateway { chargeCard(amountCents: number): Promise<ChargeResult>; }
class PaymentService { constructor(private readonly gateway: PaymentGateway) {} }

Put most of these rules into ESLint (@typescript-eslint/naming-convention) so the machine checks them; review only discusses meaning.

The NestJS docs use one consistent pattern across all examples (though it is not stated as a rule): kebab-case files with a suffix per kind, UpperCamelCase classes with the matching suffix. The CLI nest g resource orders generates the same pattern.

Kind File Class
Module orders.module.ts OrdersModule
Controller orders.controller.ts OrdersController
Service orders.service.ts OrdersService
Create DTO dto/create-order.dto.ts CreateOrderDto
Update DTO dto/update-order.dto.ts UpdateOrderDto (usually PartialType(CreateOrderDto))
Entity entities/order.entity.ts Order
Guard, pipe, decorator roles.guard.ts, tenant-id.decorator.ts RolesGuard, TenantId

Name DTOs after the action: CreateOrderDto, CancelOrderDto, not a shared OrderDto. A shared DTO gradually gains optional fields for each use case, and validation loses its meaning. See modules, providers, controllers.

Before Problem After
processData(data) Two empty words reconcileSettlementReport(report)
flag Unclear what “on” means shouldNotifyCustomer
isNotDeleted Double negation with ! isActive (or deletedAt IS NULL)
timeout: 5 Missing unit timeoutMs: 5_000
getUser() returns null Violates the team’s meaning of get findUserById()
UserManager “Manager” of everything UserRegistrationService, UserProfileService
IOrderRepo I prefix, abbreviation OrderRepository

Names in the database, APIs and events have their own tables on the following pages.

Next: PostgreSQL.