standards-typescript

This skill provides TypeScript coding standards and is automatically loaded for TypeScript projects. It includes naming conventions, best practices, and recommended tooling.

16 stars

Best use case

standards-typescript is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

This skill provides TypeScript coding standards and is automatically loaded for TypeScript projects. It includes naming conventions, best practices, and recommended tooling.

Teams using standards-typescript should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/standards-typescript/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/standards-typescript/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/standards-typescript/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How standards-typescript Compares

Feature / Agentstandards-typescriptStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

This skill provides TypeScript coding standards and is automatically loaded for TypeScript projects. It includes naming conventions, best practices, and recommended tooling.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# TypeScript Coding Standards

## Core Principles

1. **Simplicity**: Simple, understandable code
2. **Readability**: Readability over cleverness
3. **Maintainability**: Code that's easy to maintain
4. **Testability**: Code that's easy to test
5. **DRY**: Don't Repeat Yourself - but don't overdo it

## General Rules

- **Early Returns**: Use early returns to avoid nesting
- **Descriptive Names**: Meaningful names for variables and functions
- **Minimal Changes**: Only change relevant code parts
- **No Over-Engineering**: No unnecessary complexity
- **Minimal Comments**: Code should be self-explanatory. No redundant comments!

## Naming Conventions

| Element | Convention | Example |
|---------|------------|---------|
| Variables/Functions | camelCase | `getUserById`, `isActive` |
| Classes/Interfaces/Types | PascalCase | `UserService`, `ApiClient` |
| Constants | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` |
| Private | Prefix with `_` or `#` | `_internalMethod`, `#privateField` |
| Files | kebab-case or camelCase | `user-service.ts`, `userService.ts` |
| Interfaces | No `I` prefix | `User` not `IUser` |
| Type aliases | PascalCase | `UserId`, `HttpMethod` |
| Event Handlers | Prefix with `handle` | `handleClick`, `handleSubmit` |

## Project Structure

```
myproject/
├── src/
│   ├── index.ts              # Entry point
│   ├── config.ts             # Settings, env vars
│   ├── types/
│   │   └── index.ts          # Shared types
│   ├── models/
│   │   └── user.ts           # Domain models
│   ├── services/
│   │   └── user-service.ts   # Business logic
│   ├── repositories/
│   │   └── user-repo.ts      # Data access
│   └── utils/
│       └── helpers.ts        # Utility functions
├── tests/
│   ├── services/
│   │   └── user-service.test.ts
│   └── setup.ts
├── package.json
├── tsconfig.json
└── README.md
```

## Code Style

```typescript
// Use explicit types for function parameters and return values
function getUserById(userId: string): User | undefined {
  if (!userId) {
    throw new Error("userId cannot be empty");
  }
  // implementation...
}

// Prefer interfaces for object shapes
interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
}

// Use type aliases for unions, intersections, or primitives
type UserId = string;
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type Result<T> = { success: true; data: T } | { success: false; error: string };
```

## Best Practices

```typescript
// Prefer const over let
const users: User[] = [];

// Use nullish coalescing and optional chaining
const name = user?.profile?.name ?? "Anonymous";

// Prefer template literals
const message = `Hello, ${user.name}!`;

// Use destructuring
const { id, name, email } = user;
function processUser({ id, name }: User): void { }

// Prefer array methods over loops
const activeUsers = users.filter(u => u.isActive);
const userNames = users.map(u => u.name);
const totalAge = users.reduce((sum, u) => sum + u.age, 0);

// Use readonly for immutable data
interface Config {
  readonly apiUrl: string;
  readonly maxRetries: number;
}

// Use as const for literal types
const DIRECTIONS = ["north", "south", "east", "west"] as const;
type Direction = typeof DIRECTIONS[number];

// Prefer unknown over any
function parseJson(input: string): unknown {
  return JSON.parse(input);
}

// Type guards for type narrowing
function isUser(value: unknown): value is User {
  return typeof value === "object" && value !== null && "id" in value;
}
```

## Utility Types

```typescript
// Partial<T> - Make all properties optional
type UserUpdate = Partial<User>;
// { id?: string; name?: string; email?: string; age?: number }

// Pick<T, K> - Select specific properties
type UserPreview = Pick<User, "id" | "name">;
// { id: string; name: string }

// Omit<T, K> - Exclude specific properties
type UserWithoutEmail = Omit<User, "email">;
// { id: string; name: string; age?: number }

// Record<K, T> - Object with specific keys and value type
type RolePermissions = Record<"admin" | "user" | "guest", string[]>;
// { admin: string[]; user: string[]; guest: string[] }

// ReturnType<F> - Extract return type of function
type FetchResult = ReturnType<typeof fetchUser>;
// Promise<User | undefined>

// Parameters<F> - Extract parameter types
type FetchParams = Parameters<typeof fetchUser>;
// [userId: string]

// Awaited<T> - Unwrap Promise type
type ResolvedUser = Awaited<ReturnType<typeof fetchUser>>;
// User | undefined
```

## Discriminated Unions

```typescript
// Use a common "type" or "status" field as discriminator
type ApiResponse<T> =
  | { status: "success"; data: T }
  | { status: "error"; error: string }
  | { status: "loading" };

function handleResponse(response: ApiResponse<User>) {
  switch (response.status) {
    case "success":
      console.log(response.data.name); // TypeScript knows data exists
      break;
    case "error":
      console.error(response.error); // TypeScript knows error exists
      break;
    case "loading":
      console.log("Loading...");
      break;
  }
}

// State machines with discriminated unions
type AuthState =
  | { state: "idle" }
  | { state: "loading" }
  | { state: "authenticated"; user: User }
  | { state: "error"; message: string };

// Action types for reducers
type UserAction =
  | { type: "SET_USER"; payload: User }
  | { type: "CLEAR_USER" }
  | { type: "UPDATE_NAME"; payload: string };
```

## Runtime Validation with Zod

```typescript
import { z } from "zod";

// Define schema
const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(0).max(150).optional(),
});

// Infer TypeScript type from schema
type User = z.infer<typeof UserSchema>;

// Validate data (throws on error)
const user = UserSchema.parse(untrustedData);

// Safe validation (returns result object)
const result = UserSchema.safeParse(untrustedData);
if (result.success) {
  console.log(result.data); // User
} else {
  console.error(result.error.issues);
}

// Common patterns
const ConfigSchema = z.object({
  apiUrl: z.string().url(),
  timeout: z.number().default(5000),
  retries: z.number().min(0).max(10).default(3),
});

// Transform and validate
const EmailSchema = z.string().email().transform((val) => val.toLowerCase());
```

## Async/Await

```typescript
// Async function with proper typing
async function fetchUser(userId: string): Promise<User | undefined> {
  const response = await fetch(`/api/users/${userId}`);
  if (!response.ok) return undefined;
  return response.json() as Promise<User>;
}

// Use Promise.all for concurrent operations
async function fetchAllUsers(userIds: string[]): Promise<User[]> {
  const users = await Promise.all(userIds.map(fetchUser));
  return users.filter((user): user is User => user !== undefined);
}

// Handle errors with try/catch
async function safeFetch<T>(url: string): Promise<Result<T>> {
  try {
    const response = await fetch(url);
    const data = await response.json();
    return { success: true, data };
  } catch (error) {
    return { success: false, error: String(error) };
  }
}
```

## Error Handling

```typescript
// Custom error classes for domain errors
class UserNotFoundError extends Error {
  constructor(public readonly userId: string) {
    super(`User not found: ${userId}`);
    this.name = "UserNotFoundError";
  }
}

// Strict vs optional returns
function getUserStrict(userId: string): User {
  const user = repository.get(userId);
  if (!user) throw new UserNotFoundError(userId);
  return user;
}

function getUserOptional(userId: string): User | undefined {
  return repository.get(userId);
}

// Result type for explicit error handling
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };
```

## Comments - Less is More

```typescript
// BAD - redundant comment
// Get the user from database
const user = repository.getUser(userId);

// GOOD - self-explanatory code, no comment needed
const user = repository.getUser(userId);

// GOOD - comment explains WHY (not obvious)
// Rate limit: API allows max 1000 requests/min
await rateLimiter.acquire();
```

## Recommended Tooling

| Tool | Purpose |
|------|---------|
| `pnpm` or `bun` | Package manager (faster than npm) |
| `eslint` | Linting with TypeScript rules |
| `prettier` | Code formatting |
| `vitest` or `jest` | Testing framework |
| `tsx` or `ts-node` | TypeScript execution |
| `zod` | Runtime validation with type inference |

## tsconfig.json Recommendations

> **Note:** These are strict settings for new projects. For existing codebases, enable incrementally.

```json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "exactOptionalPropertyTypes": true,
    "noPropertyAccessFromIndexSignature": true,
    "forceConsistentCasingInFileNames": true,
    "verbatimModuleSyntax": true
  }
}
```

## Production Best Practices

1. **Strict mode** - Enable `strict: true` in tsconfig.json
2. **Explicit return types** - Always declare return types for public functions
3. **Avoid any** - Use `unknown` and type guards instead
4. **Readonly by default** - Use `readonly` and `as const` for immutable data
5. **Discriminated unions** - For state management and result types
6. **Dependency injection** - Pass dependencies explicitly
7. **Custom errors** - Domain-specific error classes
8. **Environment variables** - Type-safe config with validation (zod, env-var)
9. **Barrel exports** - Use index.ts for clean imports
10. **Path aliases** - Configure `@/` paths in tsconfig for cleaner imports

---

## References

- Utility Types, Discriminated Unions, and Zod sections inspired by [moai-lang-typescript](https://github.com/AJBcoding/claude-skill-eval/tree/main/skills/moai-lang-typescript) by AJBcoding

Related Skills

standards-python

16
from diegosouzapw/awesome-omni-skill

This skill provides Python coding standards and is automatically loaded for Python projects. It includes naming conventions, best practices, and recommended tooling.

standards-frontend

16
from diegosouzapw/awesome-omni-skill

Frontend component and UI development standards for modern React/Next.js applications. Includes React 19 patterns, Tailwind CSS v4, Server Components, accessibility, and the Anthropic frontend-design aesthetic philosophy.

security-environment-standards

16
from diegosouzapw/awesome-omni-skill

Security and environment configuration standards for web applications, including environment variable management, secure coding practices, and production deployment security. Use when setting up environments, configuring security, or deploying applications.

pulumi-typescript

16
from diegosouzapw/awesome-omni-skill

Pulumi infrastructure as code using TypeScript with Pulumi Cloud and ESC integration. Use when working with Pulumi TypeScript projects, ESC environments, dynamic secrets, OIDC credentials, or infrastructure automation with Node.js/TypeScript.

nodejs-backend-typescript

16
from diegosouzapw/awesome-omni-skill

Node.js backend development with TypeScript, Express/Fastify servers, routing, middleware, and database integration

modern-python-standards

16
from diegosouzapw/awesome-omni-skill

Strict adherence to modern (3.11+), idiomatic, and type-safe Python development.

moai-lang-typescript

16
from diegosouzapw/awesome-omni-skill

TypeScript best practices with modern frameworks, full-stack development, and type-safe patterns for 2025

mcp-standards

16
from diegosouzapw/awesome-omni-skill

MCP server standardization patterns for Claude Code plugins. Use when implementing MCP servers, designing tool interfaces, configuring MCP transports, or standardizing MCP naming conventions. Trigger keywords - "MCP", "MCP server", "MCP tools", "MCP transport", "tool naming", "MCP configuration".

javascript-typescript-typescript-scaffold

16
from diegosouzapw/awesome-omni-skill

You are a TypeScript project architecture expert specializing in scaffolding production-ready Node.js and frontend applications. Generate complete project structures with modern tooling (pnpm, Vite, N

global-standards

16
from diegosouzapw/awesome-omni-skill

Project-wide coding standards and conventions specialist. Use PROACTIVELY when writing code, making architectural decisions, or establishing project conventions. Covers coding style, commenting, error handling, validation, tech stack consistency, and project conventions across all languages and frameworks.

frontend-ui-tailwind-standards

16
from diegosouzapw/awesome-omni-skill

Standardized guidelines and patterns for Frontend Ui Tailwind Standards.

Frontend Responsive Design Standards

16
from diegosouzapw/awesome-omni-skill

Build responsive, mobile-first layouts using fluid containers, flexible units, media queries, and touch-friendly design that works across all screen sizes. Use this skill when creating or modifying UI layouts, responsive grids, breakpoint styles, mobile navigation, or any interface that needs to adapt to different screen sizes. Apply when working with responsive CSS, media queries, viewport settings, flexbox/grid layouts, mobile-first styling, breakpoint definitions (mobile, tablet, desktop), touch target sizing, relative units (rem, em, %), image optimization for different screens, or testing layouts across multiple devices. Use for any task involving multi-device support, responsive design patterns, or adaptive layouts.