Cheat Sheet: JavaScript (TypeScript) variable naming convention

Search for a command to run...

Recommendations on how to structure TanStack queries and mutations. Provided templates define hooks with extensible interfaces, supporting custom fetch functions per request. RSC/SSR/RCC compatible. Expectations Compatible with some RSC/SSR framewor...

Tool ni is a utility that removes the need to recognize a type of package manager in JS projects (npm, yarn, pnpm, bun). It provides a unified interface and uses appropriate commands instead (calls yarn in yarn projects, npm in npm projects, etc.). L...

Various React applications require various structures. Let's define a set of advice on how to think about project organisation and apply it to a medium-sized project. These recommendations aren't a silver bullet for every project. Apart from the "cas...

Recommendations on how to unify naming convention within a code – formats, acronyms and abbreviations, value-based prefixes, event handlers, etc. Mainly for vanilla TypeScript with a bit of React.
It is good to restrict name formats to those listed below unless there is an extraordinary reason (e.g. pairing with database column names):
camelCase – default name format,
PascalCase – format of classes, types, enum-like structures, interfaces and special structures (e.g. React component names),
SCREAMING_SNAKE_CASE – global constants.
We can use full words (properties), abbreviations (props) and acronyms within variable names.
2 letter acronyms are uppercase.
3+ letter acronyms are lowercase.
// 2 letters
const TranslationsEn = {}; // abbreviation
const enTranslations = {}; // abbreviation
const adminUI = {}; // acronym
const adminUIAdvanced = {}; // acronym
const UIButton = {}; // acronym
// 3+ letters
type ComponentProps = {}; // abbreviation
const htmlTags = []; // acronym
const copyHtml = () => {}; // acronym
All variables must be named to reflect the meaning of the stored value. The name format is chosen according to the list above. In special cases (boolean values, enums, etc.), variable names may use a unique prefix or rule to distinguish themselves from the rest.
// <variableDescription>
const result = 1;
const nextMiddleware = "logger";
// <VARIABLE_DESCRIPTION>
const ENVIRONMENT_VARIABLE = process.env.ENVIRONMENT_VARIABLE;
These variables should only contain true/false boolean (not string) values and thus implicitly declare that they are safe to use in conditions.
// (is|are)[<Noun>]<Adjective>
const isSubmitted = false;
const isFormASubmitted = false;
const isFormBSubmitted = false;
const areFormsSubmitted = isFormASubmitted && isFormBSubmitted;
// (is|are)<Action>
const isFetching = true;
// has<SubjectDescription>
const hasAtLeastOneOddNumber = true;
// Global constant with IS prefix
const IS_DEBUG_MODE = true;
Prefixes is/are have a priority over has – don't name a variable hasDefinedStatus when you can use isStatusDefined. The prefix has should be used in cases that cannot be comfortably replaced with is/are, e.g. hasTwoElementsFromArray.
Negation
Sometimes, negation is used as frequently as the original value, or we need to operate with negative statements only. In these cases, we can use a secondary Not prefix.
const isFormatted = false;
const isNotFormatted = !isFormatted;
Enums have a special behaviour - TypeScript enum as a type is not the best concept, according to the TypeScript Team. Therefore it is better to use an object with as const structure (explanation). According to Google JS Guide, we can think of this object as a special structure (PascalCase) containing constants (SCREAMING_SNAKE_CASE).
const RequestStatus = {
PENDING: 'Pending',
SUCCESS: 'Success',
ERROR: 'Error',
} as const;
type RequestStatus = (typeof RequestStatus)[keyof typeof RequestStatus];
// Usage
RequestStatus.SUCCESS;
Types use PascalCase and do not need a special prefix. Interfaces and generics have one letter prefix because of their special use cases (useful mainly in libraries).
// <TypeName>
type SystemProps = {};
// I<InterfaceName>
interface ISystemProps {}
// T<GenericType>
const createValue = <TInputValue>(value: TInputValue) => {
return value;
};
Event handlers (callbacks) are functions that are called after an event – e.g. HTML onclick, oncontextmenu, React events, etc.
// handle[<Object>]<Action>
const handleClick = () => {}; // click is clearly defined
const handleSendButtonClick = () => {}; // one of many click events
const handleSignOut = () => {} // multi-usage close callback
Object - defines unique items that we interact with. It is optional if the handler is called from multiple places or if it is unique within the code part.
Action - an action caused by a user.
React applications are a special case using onX={handleX} pairs.
type ComponentProps = {
onSignInFormSubmit: () => {};
};
const Component = ({ onSignInFormSubmit }: ComponentProps) => {};
const Parent = () => {
const handleSignInFormSubmit = () => {};
return <Component onSignInFormSubmit={handleSignInFormSubmit} />
}
It is better to not name handlers with on prefix unless you, for example, want to create an auto-spreading structure of build-in properties (using spread syntax with prop names onClick, etc.). Detailed explanation: Event Handler Naming in React (by Jake Trent).
A function is always some kind of action. Therefore, its name should begin with a verb. It is a good idea to fix a set of these verbs and describe their purpose.
// transform[Entity]to[Entity]
const transformResultToOrderedArray = () => {}
// format[Entity]As[Entity]
const formatTimestampAsLocalizedEnString = () => {}
// (generate|gen)[Entity]
const generateRandomTraceId = () => {}
const genRandomTraceId = () => {}
HTTP method functions (return a result of fetch API) should be named with a method that they return:
// <method><Entity>
const getArticles = () => {};
const postArticle = () => {};
const putArticle = () => {};
const patchArticle = () => {};
const deleteArticle = () => {};
// ...
According to Private Fields we need to use # (hash names) for private methods and attributes.
class PrivateNumber {
#x;
constructor(x) {
this.#x = x;
}
get #privateSecretValue() {
return this.#x + 10;
}
get secretValue() {
return this.#privateSecretValue;
}
}
After all, it is not so important which style, rules or prefixes we use. They just need to be consistent at least within a project. But we make our (and our colleagues) lives easier when we use at least somehow unified conventions.