No More Magic! The Power of Meaningful Constants
Ever stumbled upon a line of code like if (status === 2)
or total = price * 1.15
and wondered what on earth that 2
or 1.15
actually means? These are often called "magic numbers" or "magic strings" — values dropped into our code without any explanation. They might make sense at the moment, but they create confusion for anyone reading the code later (including our future selves!).
The solution is simple: give them a name! By defining constants, we make our code self-documenting, easier to update, and less prone to typos.
From Magic Numbers to Clear Intent
Let's look at a common scenario: calculating discounts based on user type.
// 👎 Bad: What do 'vip' and 0.2 mean?
function calculateDiscount(price: number, userType: string): number {
if (userType === 'vip') {
return price * 0.2
} else if (userType === 'premium') {
return price * 0.1
}
return price
}
This code is full of magic. The string 'vip'
and the number 0.2
are loosely floating around. If we need to change the VIP discount rate, we have to hunt down this specific number. Even worse, what if we make a typo like userType === 'vpi'
? The code will fail silently.
Now, let's give these values a home.
// 👍 Good: Clear, self-documenting, and safe
const USER_TYPES = {
VIP: 'vip',
PREMIUM: 'premium',
} as const
const DISCOUNT_RATES = {
[USER_TYPES.VIP]: 0.2,
[USER_TYPES.PREMIUM]: 0.1,
} as const
function calculateDiscount(price: number, userType: string): number {
const discountRate = DISCOUNT_RATES[userType] ?? 0
return price * (1 - discountRate)
}
Look at that!
- No More Typos: We reference
USER_TYPES.VIP
instead of typing'vip'
. If we mistype the constant, our tools will tell us immediately. - Single Source of Truth: All discount rates are in one place. Need to update the premium discount? Easy, just change it in the
DISCOUNT_RATES
object. - Clarity: The code now reads like plain English. We're getting a discount rate for a specific user type. The logic is crystal clear. I also fixed the calculation to return the discounted price, not just the discount amount.
Grouping Configuration Constants
This principle is especially useful for configuration values, like API settings or status codes.
// 👎 Bad: A loose collection of settings
const API_URL = 'https://api.example.com';
const TIMEOUT = 5000;
const MAX_RETRIES = 3;
// 👍 Good: A tidy, organized configuration object
const API_CONFIG = {
BASE_URL: 'https://api.example.com',
TIMEOUT: 5000,
MAX_RETRIES: 3,
} as const;
By grouping these into an API_CONFIG
object, we create a single, clear source for all API-related settings. It's clean, organized, and easy to import and use across your application. The same goes for things like HTTP status codes, which prevents you from having to remember if a "Not Found" error is 404
or something else.
The Takeaway
Banishing magic values is one of the quickest wins for cleaner code. By defining constants, you trade mystery for meaning. Your code becomes more readable, maintainable, and robust. So next time you're about to type a raw number or string, take a second to give it a name. Your future self will thank you for it.