Constants in TypeScript: How to Declare and Use in Classes

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Constants in TypeScript Classes: From Beginner to Professional

\n\n

Have you ever written in TypeScript and suddenly realized: "I'm using this magic string 'ADMIN' in ten places, and if I make a typo, the compiler will stay silent"? A familiar pain. Or, even worse, someone on the team changes a constant's value directly at runtime, and you spend an hour debugging to figure out why everything broke.

\n\n

Welcome to the world of class constants in TypeScript. This is not just syntactic sugar — it's the foundation of clean, predictable, and safe architecture. In this article, we'll break down all the ways to declare constants in TypeScript classes: from simple readonly to advanced techniques with as const and generics. Let's go!

\n\n

Why Constants in Classes Matter?

\n\n

Imagine you're developing an online store application. You have an Order class, and it has statuses: "pending", "shipped", "delivered". If you scatter these strings throughout the code, sooner or later someone will write "PENDING" with a capital letter — and a bug is guaranteed. TypeScript class constants solve this problem once and for all.

\n\n
    \n
  • Type safety: The compiler won't let you pass "pendingg" where "pending" is required.
  • \n
  • Readability: OrderStatus.Pending is clearer than just a string.
  • \n
  • Maintainability: Changing the value in one place changes it everywhere.
  • \n
\n\n

Method #1: readonly — The Basics, but with Nuances

\n\n

The simplest way is to use the readonly modifier. It prevents changing a field after initialization.

\n\n
class AppConfig {\n    readonly API_URL: string = 'https://api.example.com';\n    readonly MAX_RETRIES: number = 3;\n}\n\nconst config = new AppConfig();\nconsole.log(config.API_URL); // 'https://api.example.com'\n// config.API_URL = 'new-url'; // Error! Cannot assign to 'API_URL' because it is a read-only property.
\n\n

But there's a catch: readonly only works at the TypeScript level. In compiled JavaScript, these fields can still be changed. For full protection, use Object.freeze or # (private fields).

\n\n

Method #2: static readonly — The King of Constants

\n\n

If a constant is not tied to a specific class instance (which happens in 99% of cases), use static readonly. This is the classic class constant typescript pattern.

\n\n
class MathConstants {\n    static readonly PI: number = 3.14159;\n    static readonly E: number = 2.71828;\n    static readonly GOLDEN_RATIO: number = 1.61803;\n}\n\n// Access without creating an instance\nconsole.log(MathConstants.PI); // 3.14159\n// MathConstants.PI = 3.14; // Error!
\n\n

This approach is ideal for configurations, mathematical constants, statuses, and any values that should not change.

\n\n

Method #3: enum — When You Have Many Constants

\n\n

If you have a group of related constants (e.g., order statuses), enum is your best friend. It creates a named set of values.

\n\n
enum OrderStatus {\n    Pending = 'pending',\n    Shipped = 'shipped',\n    Delivered = 'delivered',\n    Cancelled = 'cancelled'\n}\n\nclass Order {\n    constructor(public status: OrderStatus) {}\n}\n\nconst order = new Order(OrderStatus.Pending);\nconsole.log(order.status); // 'pending'\n\n// order.status = 'pendingg'; // Error! Type '"pendingg"' is not assignable to type 'OrderStatus'
\n\n

Tip: If you use string enums (as in the example), they provide readable values at runtime. Numeric enums are faster, but harder to debug.

\n\n

Method #4: as const — For Maximum Strictness

\n\n

Sometimes you want an object or array to become con

Blogs

Book Recommendations