typescript

v2026.09.24

TypeScript language. Covers types, generics, and advanced patterns. Use when writing type-safe JavaScript code. USE WHEN: user mentions "typescript", "types", "generics", asks about "type safety", "type errors", "tsconfig", "utility types", "type guards", "branded types" DO NOT USE FOR: reviewing existing TypeScript code - use `review/typescript`, which covers the defects `tsc` and typescript-eslint do not report DO NOT USE FOR: Plain JavaScript without types - use `javascript` skill instead DO NOT USE FOR: Node.js runtime - use `nodejs` skill instead DO NOT USE FOR: Framework-specific typing - use framework skills (React, Vue, etc.)

GitHub
Install command
npx skhub add claude-dev-suite/typescript
Markdown
SKILL.md

TypeScript Core Knowledge

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: typescript for comprehensive documentation.

Basic Types

// Primitives
const str: string = 'hello';
const num: number = 42;
const bool: boolean = true;
const arr: number[] = [1, 2, 3];
const tuple: [string, number] = ['hello', 42];

// Objects
interface User {
  id: number;
  name: string;
  email?: string;  // Optional
  readonly createdAt: Date;
}

type Status = 'active' | 'inactive' | 'pending';  // Union

Generics

// Generic function
function identity<T>(arg: T): T {
  return arg;
}

// Generic interface
interface Repository<T> {
  find(id: string): Promise<T | null>;
  findAll(): Promise<T[]>;
  create(data: Omit<T, 'id'>): Promise<T>;
}

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

Utility Types

Partial<T>      // All properties optional
Required<T>     // All properties required
Pick<T, K>      // Select properties
Omit<T, K>      // Remove properties
Record<K, V>    // Key-value map
Readonly<T>     // All properties readonly
ReturnType<F>   // Function return type
Parameters<F>   // Function parameters
Awaited<T>      // Unwrap Promise

Advanced Patterns

// Discriminated unions
type Result<T> =
  | { success: true; data: T }
  | { success: false; error: Error };

// Type guards
function isUser(obj: unknown): obj is User {
  return typeof obj === 'object' && obj !== null && 'id' in obj;
}

// Mapped types
type Nullable<T> = { [K in keyof T]: T[K] | null };

// Template literals
type EventName = `on${Capitalize<string>}`;

Config (tsconfig.json)

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "bundler"
  }
}

When NOT to Use This Skill

ScenarioUse Instead
Plain JavaScript projectjavascript skill
Node.js runtime internalsnodejs skill
React-specific typesfrontend-react skill
Testing type assertionstesting-vitest or testing-jest skills
Type generation from schemaapi-design-openapi or framework-specific skills

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Using any everywhereDefeats type safetyUse unknown or proper types
as type assertionsRuntime errors possibleType guards or proper typing
Large union typesHard to maintainDiscriminated unions or branded types
Mixing interface and typeInconsistent codebaseChoose one convention
Ignoring strictNullChecksHidden null/undefined bugsEnable strict mode
Index signatures without boundsUnsafe accessUse Record or Map with validation
Deep nesting in genericsUnreadable typesExtract intermediate types

Quick Troubleshooting

IssueCauseSolution
"Type 'X' is not assignable to type 'Y'"Type mismatchCheck type definitions, use type guards
"Property 'x' does not exist on type"Missing or wrong typeAdd property or fix interface
"Cannot find module"Missing types or pathInstall @types or configure paths
"Object is possibly 'null'"strictNullChecks enabledUse optional chaining or null checks
"Type instantiation is excessively deep"Complex generic recursionSimplify types or add type bounds
"Index signature is missing"Accessing dynamic keysUse Record or add index signature
Build takes too longToo many files, no incrementalEnable incremental, use project references

Static Analysis & Linting

Official Rules References

ToolRules CountDocumentation
ESLint200+https://eslint.org/docs/latest/rules/
TypeScript-ESLint100+https://typescript-eslint.io/rules/
Biome200+https://biomejs.dev/linter/rules/
SonarJS422https://rules.sonarsource.com/javascript/

Key Rules to Enable

// eslint.config.js (ESLint 9+)
export default [
  {
    rules: {
      // Prevent bugs
      'no-unused-vars': 'error',
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/no-misused-promises': 'error',

      // Code quality
      '@typescript-eslint/explicit-function-return-type': 'warn',
      '@typescript-eslint/no-explicit-any': 'warn',
      'complexity': ['warn', 10],
      'max-depth': ['warn', 4],
    }
  }
];

Recommended Configs

ToolConfigCommand
ESLint@eslint/js recommendednpm init @eslint/config
TypeScript-ESLintstrict-type-checkedSee ts-eslint docs
BiomeDefaultnpx @biomejs/biome init

Production Readiness

Strict Configuration

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

Error Handling

// Type-safe error handling
class AppError extends Error {
  constructor(
    message: string,
    public readonly code: string,
    public readonly statusCode: number = 500
  ) {
    super(message);
    this.name = 'AppError';
  }
}

// Result type pattern
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E };

async function safeAsync<T>(
  promise: Promise<T>
): Promise<Result<T>> {
  try {
    const data = await promise;
    return { success: true, data };
  } catch (error) {
    return { success: false, error: error as Error };
  }
}

// Usage
const result = await safeAsync(fetchUser(id));
if (result.success) {
  console.log(result.data);
} else {
  console.error(result.error.message);
}

Type Safety Patterns

// Branded types for type safety
type UserId = string & { readonly brand: unique symbol };
type OrderId = string & { readonly brand: unique symbol };

function createUserId(id: string): UserId {
  return id as UserId;
}

// Exhaustive checking
function assertNever(x: never): never {
  throw new Error(`Unexpected value: ${x}`);
}

type Status = 'active' | 'inactive' | 'pending';

function handleStatus(status: Status): string {
  switch (status) {
    case 'active': return 'Active';
    case 'inactive': return 'Inactive';
    case 'pending': return 'Pending';
    default: return assertNever(status);
  }
}

// Zod for runtime validation
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(2),
});

type User = z.infer<typeof UserSchema>;

function parseUser(data: unknown): User {
  return UserSchema.parse(data);
}

Testing

// Type testing with expectTypeOf
import { expectTypeOf, describe, it } from 'vitest';

describe('types', () => {
  it('User has correct shape', () => {
    expectTypeOf<User>().toMatchTypeOf<{
      id: string;
      email: string;
      name: string;
    }>();
  });

  it('createUser returns User', () => {
    expectTypeOf(createUser).returns.toEqualTypeOf<User>();
  });
});

// Unit testing with proper types
import { describe, it, expect, vi } from 'vitest';

describe('UserService', () => {
  it('fetches user by id', async () => {
    const mockUser: User = {
      id: '123',
      email: 'test@example.com',
      name: 'Test',
    };

    const repository = {
      findById: vi.fn().mockResolvedValue(mockUser),
    };

    const service = new UserService(repository);
    const result = await service.getUser('123');

    expect(result).toEqual(mockUser);
    expect(repository.findById).toHaveBeenCalledWith('123');
  });
});

Performance

// Lazy initialization
class ExpensiveService {
  private static instance: ExpensiveService | null = null;

  static getInstance(): ExpensiveService {
    if (!this.instance) {
      this.instance = new ExpensiveService();
    }
    return this.instance;
  }
}

// Memoization with proper types
function memoize<Args extends unknown[], Result>(
  fn: (...args: Args) => Result
): (...args: Args) => Result {
  const cache = new Map<string, Result>();

  return (...args: Args): Result => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key)!;
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

Monitoring Metrics

MetricTarget
Type coverage> 95%
any usage0 instances
Build time< 30s
Type errors0

Checklist

  • strict: true enabled
  • noUncheckedIndexedAccess enabled
  • No explicit any usage
  • Branded types for IDs
  • Result type for error handling
  • Runtime validation with Zod
  • Type tests with expectTypeOf
  • Declaration files generated
  • Source maps enabled
  • ESLint with typescript-eslint

Reference Documentation

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: typescript for comprehensive documentation.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/languages/typescript

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1