Skip to content
cccskills
FreePublished on GitHub

typescript-best-practices

Type-safe TypeScript patterns from industry standards

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md5.9 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Purpose

Apply type-safe TypeScript patterns and best practices from industry standards.

Core Principles

Type safety over convenience
Explicit over implicit
Prefer strict mode
Use inference wisely

Rules

1. Type System

type_inference:
  rely_on: trivially inferred types (primitives, literals)
  annotate: complex expressions, return types, public APIs

any_vs_unknown:
  prefer: unknown (requires type narrowing)
  avoid: any (disables type checking)
  if_any_needed: add suppressing comment

nullable:
  prefer: "field?: Type"
  avoid: "field: Type | undefined"
  compare_enums: explicitly, not boolean coercion

patterns: |
  // Good: unknown with narrowing
  function process(data: unknown): void {
    if (typeof data === 'string') {
      console.log(data.toUpperCase());
    }
  }

  // Avoid: any
  function process(data: any): void {
    console.log(data.toUpperCase()); // No type checking!
  }

2. Interfaces vs Types

prefer_interfaces:
  - Object type definitions
  - Public API contracts
  - Extendable types

use_types_for:
  - Union types
  - Intersection types
  - Mapped types
  - Utility types

patterns: |
  // Interface for objects
  interface User {
    id: string;
    name: string;
    email: string;
  }

  // Type for unions/utilities
  type Status = 'pending' | 'active' | 'completed';
  type ReadonlyUser = Readonly<User>;

3. Arrays and Generics

array_syntax:
  simple_types: "T[]"
  complex_types: "Array<T>"

generics:
  naming: single uppercase (T, K, V) or descriptive (TItem, TResult)
  constraints: use extends for type bounds
  defaults: provide when appropriate

patterns: |
  // Array syntax
  const numbers: number[] = [1, 2, 3];
  const items: Array<{ id: string; value: number }> = [];

  // Generic constraints
  function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key];
  }

4. Variables and Constants

declarations:
  prefer: const
  when_needed: let
  never: var

one_per_statement: true

patterns: |
  // Good
  const name = 'TypeScript';
  const version = 5.0;

  // Avoid
  var name = 'TypeScript', version = 5.0;

5. Functions

function_declarations:
  named_functions: function declaration
  callbacks: arrow functions
  methods: shorthand syntax

parameters:
  prefer_rest: "...args: T[]"
  avoid: arguments object

this_handling:
  prefer: arrow functions or explicit parameter
  avoid: rebinding with bind/call/apply

patterns: |
  // Function declaration
  function processData(data: Data): Result {
    return transform(data);
  }

  // Arrow function for callbacks
  items.map((item) => item.value);

  // Rest parameters
  function concat(...strings: string[]): string {
    return strings.join('');
  }

6. Classes

visibility:
  prefer: explicit modifiers (public, private, protected)
  avoid: private fields (#)

initialization:
  prefer: at declaration site
  use: parameter properties in constructors

readonly:
  apply_to: non-reassigned properties

patterns: |
  class User {
    readonly id: string;
    private email: string;

    constructor(
      public name: string,
      email: string,
    ) {
      this.id = generateId();
      this.email = email;
    }
  }

7. Naming Conventions

UpperCamelCase:
  - Classes
  - Interfaces
  - Type aliases
  - Enums
  - Type parameters

lowerCamelCase:
  - Variables
  - Parameters
  - Functions
  - Methods
  - Properties

CONSTANT_CASE:
  - Global constants
  - Enum values
  - Static readonly fields

rules:
  - No leading/trailing underscores
  - No abbreviations (except universal: URL, ID, DNS)
  - Acronyms as whole words: loadHttpUrl, not loadHTTPURL
  - Single-letter names only in 10-line scopes

8. Control Flow

braces:
  always: use braces for all control statements

equality:
  always: "=== and !=="
  never: "== and !="

loops:
  arrays: for...of
  objects: for...in with hasOwnProperty check

patterns: |
  // Always braced
  if (condition) {
    doSomething();
  }

  // for...of for arrays
  for (const item of items) {
    process(item);
  }

  // for...in with check
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      process(obj[key]);
    }
  }

9. Error Handling

throwing:
  only: Error instances
  with_message: descriptive error messages

catching:
  type: unknown
  validate: before use

empty_catch:
  require: rationale comment

patterns: |
  // Throw Error instances
  throw new Error('Invalid input');

  // Catch with unknown
  try {
    riskyOperation();
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error(error.message);
    }
    throw error;
  }

10. Imports and Exports

imports:
  prefer: named imports
  use_namespace: for large APIs
  prefer_relative: within project

exports:
  prefer: named exports
  avoid: default exports

patterns: |
  // Named imports
  import { User, UserService } from './user';

  // Namespace import for large APIs
  import * as fs from 'fs';

  // Named exports
  export interface User { }
  export function createUser() { }

11. Disallowed Features

never_use:
  - eval() or dynamic code evaluation
  - with statements
  - const enum (use plain enum)
  - debugger statements in production
  - Modifying built-in prototypes
  - Wrapper objects (new String(), new Boolean())
  - Automatic semicolon insertion reliance

Application

When writing or reviewing TypeScript code:

  1. Always enable strict mode
  2. Always use explicit return types for public APIs
  3. Prefer unknown over any
  4. Prefer interfaces for object types
  5. Use const by default
  6. Use triple equals exclusively
  7. Handle errors with typed catch blocks
  8. Avoid default exports

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Pre-action boundary checking — validates agent tool calls against declared capabilities and task contracts

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

Auto-detect project context and optimize harness — deactivate unused agents/skills, suggest missing experts, generate project profile

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

Adversarial code review using attacker mindset — trust boundary, attack surface, business logic, and defense evaluation

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

Apache Airflow best practices for DAG authoring, testing, and production deployment

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

Alembic migration patterns for naming conventions, safety checks, expand-contract, env.py configuration, and CI integration

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

Pre-routing ambiguity analysis — scores request clarity and asks clarifying questions when needed (inspired by ouroboros)

The English summary is being prepared. Showing the original description.

baekenough/second-brain15Updated Oct 8, 2026

See all skills by baekenough

Report a problem with this skill