askill
typescript-standards

typescript-standardsSafety 100Repository

TypeScript coding standards for Oh My Brand! theme. Strict mode, interfaces, type definitions, classes, DOM manipulation, and patterns. Use when writing TypeScript components, utilities, or Web Components.

0 stars
1.2k downloads
Updated 1/10/2026

Package Files

Loading files...
SKILL.md

TypeScript Standards

TypeScript coding standards and patterns for the Oh My Brand! WordPress FSE theme.


When to Use

  • Writing TypeScript components or utilities
  • Creating Web Components for block frontends
  • Building editor components (edit.tsx)
  • Working with DOM manipulation
  • Defining type interfaces

Reference Files

FilePurpose
GalleryCarousel-example.tsFull class example (~110 lines)
utility-functions.tsDebounce/throttle utilities (~60 lines)

File Structure

/**
 * Module description.
 */

// Imports - external first, then internal
import { someFunction } from 'external-library';
import { helperFunction } from '../utils/helper';

// Types and interfaces
interface ComponentOptions {
    readonly selector: string;
    animationDuration?: number;
}

// Constants
const DEFAULT_DURATION = 300;

// Main implementation
export class ComponentName { }

// Module initialization
export function initComponent(): void { }

Strict Mode

TypeScript strict: true is enforced. All client-side code must be TypeScript (no .js files in src/).


Type Definitions

Interfaces vs Types

// Interface for object shapes
interface GalleryImage {
    readonly id: number;
    url: string;
    alt: string;
}

// Interface for options
interface CarouselOptions {
    readonly visibleCount: number;
    autoplay?: boolean;
}

// Type for unions
type GalleryLayout = 'grid' | 'masonry' | 'carousel';

// Type for function signatures
type ImageClickHandler = (image: GalleryImage, index: number) => void;

Readonly Properties

interface BlockConfig {
    readonly id: string;
    readonly type: string;
    options: BlockOptions; // Can be modified
}

class Gallery {
    private readonly element: HTMLElement;
    private readonly images: readonly GalleryImage[];
}

Naming Conventions

TypeConventionExample
ClassesPascalCaseGalleryCarousel
InterfacesPascalCaseCarouselOptions
FunctionscamelCaseinitCarousel()
VariablescamelCasecurrentIndex
ConstantsSCREAMING_SNAKEDEFAULT_DURATION
Private fields# prefix#currentIndex
Fileskebab-casegallery-carousel.ts

Classes

export class GalleryCarousel {
    readonly #element: HTMLElement;
    readonly #options: Required<CarouselOptions>;
    #currentIndex = 0;

    constructor(element: HTMLElement, options: CarouselOptions = {}) {
        this.#element = element;
        this.#options = this.#mergeOptions(options);
        this.#init();
    }

    public goToSlide(index: number): void {
        this.#currentIndex = this.#normalizeIndex(index);
        this.#updateSlides();
    }

    public getCurrentIndex(): number {
        return this.#currentIndex;
    }

    public destroy(): void {
        this.#removeEventListeners();
    }

    #init(): void { }
    #mergeOptions(options: CarouselOptions): Required<CarouselOptions> { }
    #normalizeIndex(index: number): number { }
}

See GalleryCarousel-example.ts for the full implementation.


Functions

export function debounce<T extends (...args: unknown[]) => unknown>(
    func: T,
    wait: number
): (...args: Parameters<T>) => void {
    let timeoutId: ReturnType<typeof setTimeout> | null = null;

    return function (this: unknown, ...args: Parameters<T>): void {
        if (timeoutId !== null) clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(this, args);
            timeoutId = null;
        }, wait);
    };
}

See utility-functions.ts for debounce and throttle implementations.


DOM Manipulation

Type-Safe Queries

function getElement<T extends HTMLElement>(
    selector: string,
    parent: ParentNode = document
): T | null {
    return parent.querySelector<T>(selector);
}

// Usage
const gallery = getElement<HTMLDivElement>('.gallery');
const buttons = getElements<HTMLButtonElement>('[data-action]');

Null Handling

// Early return
const element = document.querySelector<HTMLElement>('.gallery');
if (!element) return;

// Optional chaining
const width = element?.offsetWidth ?? 0;

// Assertion (use sparingly)
const button = document.querySelector<HTMLButtonElement>('.btn')!;

Event Handling

Arrow Function Methods

class Component {
    #handleClick = (event: MouseEvent): void => {
        event.preventDefault();
        this.#doSomething();
    };

    #bindEvents(): void {
        this.addEventListener('click', this.#handleClick);
    }

    #unbindEvents(): void {
        this.removeEventListener('click', this.#handleClick);
    }
}

Custom Events

this.dispatchEvent(
    new CustomEvent('gallery:slide-change', {
        bubbles: true,
        detail: { index: this.#currentIndex, total: this.#slideCount },
    })
);

Exports

Named Exports Only

// ✅ Good - named exports
export class GalleryCarousel { }
export function initGallery(): void { }
export type { CarouselOptions, GalleryImage };

// ❌ Bad - default exports
export default class GalleryCarousel { }

Anti-Patterns

AvoidUse Instead
anyProper types or generics
varconst (preferred) or let
Non-null assertion (!) without reasonNull handling with guards
Implicit return typesExplicit return types

ESLint Validation

This project uses ESLint with TypeScript-specific rules. Key rules to follow:

No Unused Variables

ESLint disallows unused variables, parameters, and imports:

/* ❌ Bad - unused parameter causes eslint error */
function updateDisplay(element: HTMLElement, value: number, isFinal: boolean): void {
    element.textContent = value.toString();
    // isFinal is never used!
}

/* ✅ Good - remove unused parameters */
function updateDisplay(element: HTMLElement, value: number): void {
    element.textContent = value.toString();
}

/* ✅ Good - prefix with underscore if intentionally unused */
function callback(_event: Event, data: string): void {
    console.log(data);
}

Key Principles

  1. Remove unused variables, parameters, and imports
  2. Prefix intentionally unused parameters with _ (underscore)
  3. Follow all rules defined in the project's ESLint configuration

Validation

Always run ESLint after making TypeScript/JavaScript changes:

pnpm run lint:js

Fix any issues before committing. This ensures consistent code style and catches common errors.


Related Skills


References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

86/100Analyzed 2/24/2026

Comprehensive TypeScript coding standards document with extensive code examples, clear sections covering strict mode, types, classes, DOM manipulation, and ESLint validation. Well-structured with "When to Use" guidance, reference files, and related skills. Slightly project-specific but contains highly reusable patterns. Strong clarity and actionability with proper metadata and tags.

100
90
70
85
85

Metadata

Licenseunknown
Version-
Updated1/10/2026
PublisherWesleySmits

Tags

githublinting