Naming Conventions in TypeScript: Best Practices for Classes, Functions, Types, Interfaces, Variables and Parameters
I've reviewed code where a variable named data was used 14 times in one file. Each one meant something different. The person who wrote it understood it pe...
19 Apr 2024

I've reviewed code where a variable named data was used 14 times in one file. Each one meant something different. The person who wrote it understood it perfectly. Nobody else did.
Naming is the hardest part of programming because it forces you to understand what the thing actually does. A bad name hides intent. A good name reveals it.
Classes: nouns that describe responsibility
A class represents a thing. Name it with a noun or noun phrase that tells you what it's responsible for. Use PascalCase.
class ProductService {} // clear — manages product operations
class OrderValidator {} // clear — validates orders
class Data {} // useless — data of what?
The name should make the class's job obvious without opening the file.
Functions: verbs that describe action
A function does something. Start with a verb. Use camelCase.
function calculateTotalPrice(items: Item[]): number {} // clear action
function processPayment(order: Order): Receipt {} // clear action
function handle(x: any): any {} // handle what?
If you can't name a function with a single verb phrase, it's probably doing too much. Split it.
Parameters: context without ambiguity
Parameters are the inputs to your functions. Name them so someone reading the function signature understands what to pass without reading the body.
// Bad — what does 'n' mean? What's 'flag'?
function process(n: number, flag: boolean): void {}
// Good — intent is obvious
function retryRequest(maxAttempts: number, shouldLog: boolean): void {}
Avoid single-letter names. Avoid temp, data, val, item when a more specific name exists.
Types and interfaces: shape of the data
Types describe structure. Name them with nouns in PascalCase, like classes.
There are two common conventions for distinguishing interfaces from types. Pick one and stick with it across your project:
// Convention 1: prefix interfaces with 'I'
interface IProduct {
id: number;
name: string;
price: number;
}
// Convention 2: suffix types with 'Type'
type ProductCategoryType = 'Digital' | 'Non-Digital';
I personally prefer no prefix — just Product for the interface. But consistency within a codebase matters more than which convention you choose.
Variables: meaning over brevity
A variable stores a value. Its name should explain what that value represents.
const totalPrice: number = calculateTotalPrice(items); // clear
const tp: number = calc(i); // cryptic
Longer names cost you nothing at runtime (they're minified in production) but save significant time when reading.
The trade-off
Good names take longer to write. You'll stare at a function for 30 seconds trying to pick the right verb. That's time well spent. Code is read ten times more than it's written. Every minute you invest in naming saves ten minutes of confusion later.
The one risk: over-naming. getUserFromDatabaseByEmailAddressString is too much. Find the balance between precision and brevity.