MCPInstall

typescript-variables

Apply, review, and explain TypeScript variable conventions. Use automatically for tasks involving variable declarations, const assertions, enum alternatives, literal-union state modelling, boolean flags, or choosing between null and undefined.

Installs
3.9K
Last 24h
+134
Trending rank
#1582
Security
Pass

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/mkosir/typescript-style-guide --skill typescript-variables
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads typescript-variables automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

Security audits

Independent scans of the skill's instructions and bundled files.

Gen Agent Trust Hub PassSAFE ·This skill provides documentation and guidance on TypeScript variable conventions, such as const assertions, enum alternatives, and state modeling. It contains no executable scripts, network operations, or sensitive file access.
Socket PassNo alerts
Snyk PassLOW ·Risk: LOW · No issues

SKILL.md

The instructions your agent reads when the skill is triggered.

Variables

Apply the TypeScript Style Guide's variable conventions in the context of the current task.

Workflow

  1. Inspect the consuming repository's conventions and configuration.
  2. Let explicit repository conventions take precedence over this opinionated guidance.
  3. Apply, review, or explain only the guidance relevant to the task.
  4. State important tradeoffs when the appropriate choice depends on context or judgment.

Boundaries

  • Keep TypeScript and ESLint responsible for checks they can enforce automatically.
  • Do not introduce unrelated TypeScript Style Guide conventions merely because this skill is active.

Related Guidance

Application State

For detailed guidance on states that require different data, use typescript-discriminated-unions when it is available.

<!-- BEGIN CANONICAL GUIDE CONTENT -->

Variables

Const Assertion

Strive to declare constants using the const assertion as const:

Constants are used to represent values that are not meant to change, ensuring reliability and consistency in a codebase. Const assertions preserve literal types and infer readonly properties.

  • Type Narrowing - Using as const ensures that literal values (e.g., numbers, strings) are treated as exact values instead of generalized types like number or string.
  • Readonly Properties - Objects and arrays get readonly properties, so TypeScript catches direct mutations.

Examples:

  • Objects

    // ❌ Avoid
    const FOO_LOCATION = { x: 50, y: 130 }; // Type { x: number; y: number; }
    FOO_LOCATION.x = 10;
    
    // ✅ Use
    const FOO_LOCATION = { x: 50, y: 130 } as const; // Type '{ readonly x: 50; readonly y: 130; }'
    FOO_LOCATION.x = 10; // Error
    
  • Arrays

    // ❌ Avoid
    const BAR_LOCATION = [50, 130]; // Type number[]
    BAR_LOCATION.push(10);
    
    // ✅ Use
    const BAR_LOCATION = [50, 130] as const; // Type 'readonly [50, 130]'
    BAR_LOCATION.push(10); // Error
    
  • Template Literals

    // ❌ Avoid
    const RATE_LIMIT = 25;
    const RATE_LIMIT_MESSAGE = `Max number of requests/min is ${RATE_LIMIT}.`; // Type string
    
    // ✅ Use
    const RATE_LIMIT = 25;
    const RATE_LIMIT_MESSAGE = `Max number of requests/min is ${RATE_LIMIT}.` as const; // Type 'Max number of requests/min is 25.'
    

Enums & Const Assertion

Enums are discouraged in the TypeScript ecosystem due to their runtime cost and quirks.
The TypeScript documentation outlines several pitfalls, and TypeScript 5.8 introduced the --erasableSyntaxOnly flag to disable runtime-generating features like enums altogether.

<Rule href="https://eslint.org/docs/latest/rules/no-restricted-syntax">{'no-restricted-syntax': [ 'error', { selector: 'TSEnumDeclaration', message: 'Replace enum with a literal type or a const assertion.', }, ]}</Rule>

As a rule of thumb, prefer:

  • Literal types whenever possible.
  • Const assertion arrays when looping through values.
  • Const assertion objects when enumerating arbitrary values.

Examples:

  • Use literal types to avoid runtime objects and reduce bundle size.

    // ❌ Avoid using enums as they increase the bundle size
    enum UserRole {
      GUEST = 'guest',
      MODERATOR = 'moderator',
      ADMINISTRATOR = 'administrator',
    }
    
    // Transpiled JavaScript
    ('use strict');
    var UserRole;
    (function (UserRole) {
      UserRole['GUEST'] = 'guest';
      UserRole['MODERATOR'] = 'moderator';
      UserRole['ADMINISTRATOR'] = 'administrator';
    })(UserRole || (UserRole = {}));
    
    // ✅ Use literal types - Types are stripped during transpilation
    type UserRole = 'guest' | 'moderator' | 'administrator';
    
    const isGuest = (role: UserRole) => role === 'guest';
    
  • Use const assertion arrays when looping through values.

    // ❌ Avoid using enums
    enum USER_ROLES {
      guest = 'guest',
      moderator = 'moderator',
      administrator = 'administrator',
    }
    
    // ✅ Use const assertions arrays
    const USER_ROLES = ['guest', 'moderator', 'administrator'] as const;
    type UserRole = (typeof USER_ROLES)[number];
    
    const seedDatabase = () => {
      USER_ROLES.forEach((role) => {
        db.roles.insert(role);
      }
    }
    const insert = (role: UserRole) => {...
    
    const UsersRoleList = () => {
      return (
        <div>
          {USER_ROLES.map((role) => (
            <Item key={role} role={role} />
          ))}
        </div>
      );
    };
    const Item = ({ role }: { role: UserRole }) => {...
    
  • Use const assertion objects when enumerating arbitrary values.

    // ❌ Avoid using enums
    enum COLORS {
      primary = '#B33930',
      secondary = '#113A5C',
      brand = '#9C0E7D',
    }
    
    // ✅ Use const assertions objects
    const COLORS = {
      primary: '#B33930',
      secondary: '#113A5C',
      brand: '#9C0E7D',
    } as const;
    
    type Colors = typeof COLORS;
    type ColorKey = keyof Colors; // Type "primary" | "secondary" | "brand"
    type ColorValue = Colors[ColorKey]; // Type "#B33930" | "#113A5C" | "#9C0E7D"
    
    const setColor = (color: ColorValue) => {...
    
    setColor(COLORS.primary);
    setColor('#B33930');
    

Type Union & Boolean Flags

Embrace type unions, especially when type union options are mutually exclusive, instead multiple boolean flag variables.

Boolean flags have a tendency to accumulate over time, leading to confusing and error-prone code, since they hide the actual app state.

// ❌ Avoid introducing multiple boolean flag variables
const isPending, isProcessing, isConfirmed, isExpired;

// ✅ Use type union variable
type UserStatus = 'pending' | 'processing' | 'confirmed' | 'expired';
const userStatus: UserStatus;

Use a literal union when only the state value changes. When each state requires different data, use a discriminated union to represent the valid states explicitly.

Null & Undefined

With strictNullChecks, null and undefined have distinct types and meanings. Use them consistently based on what absence means in the application.
Strive to:

  • Use null when a value is explicitly empty, such as an assignment or function return value.
  • Use undefined when a value is missing or omitted, such as an optional field in a form, request payload, or database query (Prisma differentiation).
<!-- END CANONICAL GUIDE CONTENT -->

FAQ

What does the typescript-variables skill do?

Apply, review, and explain TypeScript variable conventions. Use automatically for tasks involving variable declarations, const assertions, enum alternatives, literal-union state modelling, boolean flags, or choosing between null and undefined.

How do I install typescript-variables?

Run npx skills add https://github.com/mkosir/typescript-style-guide --skill typescript-variables in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/typescript-variables/ (personal) or .claude/skills/typescript-variables/ (project).

Which AI agents can use typescript-variables?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is typescript-variables safe to install?

Security partners have reviewed it: Gen Agent Trust Hub passed; Socket passed; Snyk passed. As with any skill, read the SKILL.md and bundled scripts before installing.

Who maintains typescript-variables?

It is published by mkosir in mkosir/typescript-style-guide. It has 3,928 recorded installs.

More from mkosir/typescript-style-guide

View all →

typescript-discriminated-unions

mkosir/typescript-style-guide

Apply, review, and explain discriminated unions in TypeScript. Use automatically for tasks involving mutually exclusive variants, invalid state prevention, exhaustiveness checking, variant-specific object properties, application state, function arguments, or React props.

typescript-style-guide

mkosir/typescript-style-guide

Open the skill to read its SKILL.md instructions.

typescript-naming

mkosir/typescript-style-guide

Open the skill to read its SKILL.md instructions.

typescript-types

mkosir/typescript-style-guide

Open the skill to read its SKILL.md instructions.

Popular code quality & workflow skills

View category →

grill-me

mattpocock/skills

A relentless interview to sharpen a plan or design.

Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.

handoff

mattpocock/skills

Compact the current conversation into a handoff document for another agent to pick up.

domain-modeling

mattpocock/skills

Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.

codebase-design

mattpocock/skills

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.

diagnosing-bugs

mattpocock/skills

Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.