Skip to content

Instantly share code, notes, and snippets.

@eonist
Created July 24, 2025 18:01
Show Gist options
  • Save eonist/18517d93d9ff5b6a63de6735e1fe2e4e to your computer and use it in GitHub Desktop.
Save eonist/18517d93d9ff5b6a63de6735e1fe2e4e to your computer and use it in GitHub Desktop.
Const in typescript best practice

GlobalConst.ts is an acceptable name, especially if the constants are indeed global and used across various parts of the plugin. However, in TypeScript/JavaScript, more descriptive names are generally preferred, and the concept of "global" might sometimes indicate a lack of clear scope.

Here are some better names and considerations, depending on the nature of the constants:

  1. constants.ts: This is a very common and straightforward name for a file containing a collection of related constants. It's concise and clear.
  2. config.ts or settings.ts: If the constants are primarily configuration values or settings for the application/plugin, these names are more appropriate.
  3. enums.ts: If the constants are strictly enumerations (e.g., a set of related named values), using TypeScript enums and placing them in a file named enums.ts is a standard practice.
  4. appConstants.ts or pluginConstants.ts: If the constants are specific to the application or plugin itself, adding a prefix can improve clarity and avoid naming conflicts in larger projects.
  5. [FeatureName]Constants.ts: If the constants are related to a specific feature or module, it's often better to collocate them with that feature (e.g., userConstants.ts if they relate to user management, or uiConstants.ts if they are UI-specific). This improves modularity and makes it easier to find relevant constants.

General Best Practices for Constants in TypeScript:

  • Use const keyword: Always use const for constants to ensure immutability.
  • Uppercase Naming: Constants are typically named in SCREAMING_SNAKE_CASE (e.g., MAX_RETRIES, DEFAULT_TIMEOUT).
  • Export Clearly: Export constants individually or as a group.
    // constants.ts
    export const API_BASE_URL = 'https://api.example.com';
    export const DEFAULT_PAGE_SIZE = 10;
  • Scope: Avoid truly "global" constants if they can be scoped more narrowly. If a constant is only used within a specific module or component, define it within that module rather than in a central GlobalConst.ts file. This reduces coupling and makes code easier to maintain.
  • Type Safety: Ensure constants are properly typed, especially if they are complex objects or arrays.

In summary, while GlobalConst.ts is not inherently bad, constants.ts is a more common and generally preferred generic name. For more specific sets of constants, consider config.ts, enums.ts, or feature-specific constant files.

Storing constants in a class in TypeScript is generally not recommended for simple, static constants. While it's technically possible, it often introduces unnecessary complexity and goes against common TypeScript/JavaScript patterns for managing constants.

Here's why and what alternatives are usually preferred:

Why it's generally not recommended to use a class for constants:

  1. Unnecessary Instantiation/Context: If you put constants in a class, you either need to make them static (which is better) or instantiate the class to access them. Instantiating a class just for constants is wasteful.
    // Less ideal: Need to instantiate or use static
    class AppConstants {
        static readonly API_URL = 'https://api.example.com';
        // or
        // readonly API_URL = 'https://api.example.com'; // Requires instantiation
    }
    
    // Access:
    // AppConstants.API_URL; // If static
    // new AppConstants().API_URL; // If not static
  2. Increased Bundle Size (potentially): While modern bundlers are smart, a class structure can sometimes lead to less efficient tree-shaking compared to simple exports, especially if methods are also present.
  3. Goes Against Convention: The most common and idiomatic way to handle constants in TypeScript/JavaScript is through direct named exports.

Preferred Alternatives:

  1. Plain export const (Most Common and Recommended): This is the simplest, most direct, and widely accepted way to define and export constants. It offers excellent tree-shaking capabilities and clear intent.
    // constants.ts
    export const API_BASE_URL = 'https://api.example.com';
    export const DEFAULT_TIMEOUT_MS = 5000;
    export const MAX_RETRIES = 3;
    You then import them directly where needed:
    // some-module.ts
    import { API_BASE_URL, DEFAULT_TIMEOUT_MS } from '../utils/constants';
    
    fetch(API_BASE_URL, { timeout: DEFAULT_TIMEOUT_MS });
  2. Enums (for a related set of distinct values): If your constants represent a fixed set of related values, especially for categorizing things, enums are a type-safe and readable choice.
    // AppStatus.ts
    export enum AppStatus {
        LOADING = 'LOADING',
        READY = 'READY',
        ERROR = 'ERROR',
    }
    Usage:
    import { AppStatus } from './AppStatus';
    let currentStatus: AppStatus = AppStatus.LOADING;
  3. Plain Object (if you want to group them under a single namespace-like import): You can group related constants within a single object and export that object. This allows for a single import statement to bring in a "namespace" of constants.
    // appSettings.ts
    export const AppSettings = {
        MAX_USERS: 100,
        DEFAULT_THEME: 'dark',
        DEBUG_MODE: true,
    };
    Usage:
    import { AppSettings } from '../utils/appSettings';
    
    if (AppSettings.DEBUG_MODE) {
        console.log('Debugging enabled');
    }
    This is functionally very similar to a class with static readonly properties but without the class overhead.

When a Class Might Be Considered (but often still avoidable):

  • When constants are deeply nested or have associated methods/logic: If you have a complex set of constants that logically belong together and perhaps even have helper methods that operate on them, a class (or more commonly, a namespace in TypeScript or a plain object with methods) could be considered. However, for constants alone, it's usually overkill. Example (less common for simple constants, but an example of when a class might be used for related static utilities):
    class DateUtils {
        static readonly MS_PER_SECOND = 1000;
        static readonly SECONDS_PER_MINUTE = 60;
    
        static convertMinutesToMs(minutes: number): number {
            return minutes * DateUtils.SECONDS_PER_MINUTE * DateUtils.MS_PER_SECOND;
        }
    }

Conclusion:

For most constant storage, stick to export const in a dedicated file (like constants.ts or config.ts), or use enum for sets of related, distinct values. These approaches are cleaner, more idiomatic, and provide better tooling support (e.g., for tree-shaking). Avoid classes for constants unless there's a very specific reason related to grouping with associated static utility methods, and even then, consider plain objects or namespaces first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment