TypeScript 5.x development with type system, generics, utility types, and strict mode patterns. Use when writing TypeScript code or adding types to JavaScript projects.
Provides TypeScript 5.x development support with modern patterns, strict mode, generics, and utility types. Automatically loads when `tsconfig.json` is present or `.ts`/`.tsx` files exist in the project.
/plugin marketplace add FortiumPartners/ensemble/plugin install ensemble-development@ensembleThis skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdREFERENCE.mdTypeScript 5.x development with modern patterns including strict mode, generics, utility types, and modules.
Progressive Disclosure: Quick reference patterns here. See REFERENCE.md for advanced topics.
Loaded by backend-developer or frontend-developer when:
tsconfig.json present in projectpackage.json contains typescript dependency.ts or .tsx files in project// Primitives
const name: string = "Alice";
const age: number = 30;
const isActive: boolean = true;
// Arrays and Tuples
const numbers: number[] = [1, 2, 3];
const point: [number, number] = [10, 20];
const rest: [string, ...number[]] = ["scores", 1, 2, 3];
// Interfaces - object shapes, extensible, declaration merging
interface User {
id: string;
name: string;
email: string;
}
interface Admin extends User {
permissions: string[];
}
// Type aliases - unions, tuples, primitives, complex types
type ID = string | number;
type Point = [number, number];
type Callback = (data: string) => void;
type AdminUser = User & { permissions: string[] };
// Basic function
function greet(name: string): string {
return `Hello, ${name}`;
}
// Arrow with optional/default params
const createUser = (name: string, age?: number, role = "user") => ({ name, age, role });
// Function overloads
function parse(input: string): string[];
function parse(input: string[]): string;
function parse(input: string | string[]): string | string[] {
return typeof input === "string" ? input.split(",") : input.join(",");
}
// Union - one of multiple types
type Status = "pending" | "approved" | "rejected";
type Result = string | Error;
// Intersection - combine types
type Timestamped = { createdAt: Date; updatedAt: Date };
type Entity = User & Timestamped;
type Direction = "north" | "south" | "east" | "west";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
// Template literal types
type EventName = `on${Capitalize<string>}`;
type Getter<T extends string> = `get${Capitalize<T>}`;
// typeof guard
function format(value: string | number): string {
return typeof value === "string" ? value.trim() : value.toFixed(2);
}
// in operator
function speak(animal: { bark(): void } | { meow(): void }): void {
if ("bark" in animal) animal.bark();
else animal.meow();
}
// Discriminated unions (recommended)
type Success = { status: "success"; data: string };
type Failure = { status: "failure"; error: Error };
type Result = Success | Failure;
function handle(result: Result): string {
return result.status === "success" ? result.data : result.error.message;
}
function identity<T>(value: T): T {
return value;
}
interface Box<T> {
value: T;
map<U>(fn: (value: T) => U): Box<U>;
}
class Container<T> {
constructor(private value: T) {}
get(): T { return this.value; }
}
// extends constraint
function getLength<T extends { length: number }>(item: T): number {
return item.length;
}
// keyof constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Default type
interface ApiResponse<T = unknown> {
data: T;
status: number;
}
interface User {
id: string;
name: string;
email: string;
age: number;
}
type PartialUser = Partial<User>; // All optional
type RequiredUser = Required<PartialUser>; // All required
type ReadonlyUser = Readonly<User>; // All readonly
type UserPreview = Pick<User, "id" | "name">;
type UserWithoutEmail = Omit<User, "email">;
type UserRoles = Record<string, "admin" | "user">;
// Extract/Exclude from unions
type Numbers = Extract<string | number | boolean, number>; // number
type NotNumber = Exclude<string | number | boolean, number>; // string | boolean
// Remove null/undefined
type Defined = NonNullable<string | null | undefined>; // string
// Function types
type Return = ReturnType<typeof createUser>;
type Params = Parameters<typeof createUser>;
// Unwrap Promise
type Unwrapped = Awaited<Promise<string>>; // string
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"declaration": true,
"outDir": "./dist",
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
| Flag | Purpose |
|---|---|
strict | Enable all strict checks |
noImplicitAny | Error on implicit any |
strictNullChecks | null/undefined require handling |
noUncheckedIndexedAccess | Index access may be undefined |
// Named exports
export const PI = 3.14159;
export function calculate(r: number): number { return PI * r ** 2; }
export interface Circle { radius: number; }
// Default export
export default class Calculator { }
// Re-exports
export { User } from "./user";
export * from "./utils";
// Type-only imports
import type { User } from "./types";
export type { Config } from "./config";
// types.d.ts
declare module "untyped-library" {
export function process(input: string): string;
}
// Extend existing module
declare module "express" {
interface Request { userId?: string; }
}
// Global declarations
declare global {
interface Window { myApp: { version: string }; }
}
// User-defined type guard
function isString(value: unknown): value is string {
return typeof value === "string";
}
function isUser(obj: unknown): obj is User {
return typeof obj === "object" && obj !== null && "id" in obj && "name" in obj;
}
// Assertion function
function assertDefined<T>(value: T | undefined): asserts value is T {
if (value === undefined) throw new Error("Value is undefined");
}
// Prevent type confusion
type UserId = string & { readonly brand: unique symbol };
type OrderId = string & { readonly brand: unique symbol };
function createUserId(id: string): UserId { return id as UserId; }
function createOrderId(id: string): OrderId { return id as OrderId; }
function getUser(id: UserId): User { /* ... */ }
const userId = createUserId("user-123");
getUser(userId); // OK
// getUser(createOrderId("order-456")); // Error!
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function divide(a: number, b: number): Result<number, string> {
if (b === 0) return { success: false, error: "Division by zero" };
return { success: true, data: a / b };
}
const result = divide(10, 2);
if (result.success) console.log(result.data);
else console.error(result.error);
const value = someValue as string; // Type assertion
const element = document.getElementById("app")!; // Non-null assertion
const config = { api: "/api" } as const; // Const assertion
interface StringMap { [key: string]: string; }
interface NumberMap { [index: number]: string; }
interface DataAttrs { [key: `data-${string}`]: string; }
type Optional<T> = { [K in keyof T]?: T[K] };
type Immutable<T> = { readonly [K in keyof T]: T[K] };
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.