TypeScript type safety including type guards and advanced type system features. **ALWAYS use when writing ANY TypeScript code (frontend AND backend)** to ensure strict type safety, avoid `any` types, and leverage the type system. Examples - "create function", "implement class", "define interface", "type guard", "discriminated union", "type narrowing", "conditional types", "handle unknown types".
Enforces strict TypeScript type safety by eliminating `any` types and using advanced type system features. Automatically applies when writing TypeScript code to catch errors at compile time.
/plugin marketplace add marcioaltoe/claude-craftkit/plugin install architecture-design@claude-craftkitThis skill inherits all available tools. When active, it can use any tool Claude has access to.
You are an expert in TypeScript's type system and type safety. You guide developers to write type-safe code that leverages TypeScript's powerful type system to catch errors at compile time.
For development workflow and quality gates (pre-commit checklist, bun commands), see project-workflow skill
You should proactively assist when:
unknown types in any context// ✅ GOOD: Each context owns its types
// contexts/auth/domain/types/user.types.ts
export interface AuthUser {
id: string;
email: string;
isActive: boolean;
}
// contexts/tax/domain/types/calculation.types.ts
export interface TaxCalculation {
ncmCode: string;
rate: number;
amount: number;
}
// ❌ BAD: Shared generic types that couple contexts
// shared/types/base.types.ts
export interface BaseEntity<T> {
// NO! Creates coupling
id: string;
data: T;
}
any// ❌ FORBIDDEN - Disables type checking
function process(data: any) {
return data.value; // No type safety at all
}
// ✅ CORRECT - Use unknown with type guards
function process(data: unknown): string {
if (isProcessData(data)) {
return data.value; // Type-safe access
}
throw new TypeError("Invalid data structure");
}
interface ProcessData {
value: string;
}
function isProcessData(data: unknown): data is ProcessData {
return (
typeof data === "object" &&
data !== null &&
"value" in data &&
typeof (data as ProcessData).value === "string"
);
}
// ✅ Type predicate (narrows type)
function isString(value: unknown): value is string {
return typeof value === "string";
}
function isNumber(value: unknown): value is number {
return typeof value === "number";
}
function isObject(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
// ✅ Complex type guard
interface User {
id: string;
email: string;
name: string;
}
function isUser(value: unknown): value is User {
if (!isObject(value)) return false;
return (
"id" in value &&
typeof value.id === "string" &&
"email" in value &&
typeof value.email === "string" &&
"name" in value &&
typeof value.name === "string"
);
}
// Usage
function processUser(data: unknown): User {
if (!isUser(data)) {
throw new TypeError("Invalid user data");
}
// TypeScript knows data is User here
return data;
}
// ✅ Discriminated unions for polymorphic data
type PaymentMethod =
| {
type: "credit_card";
cardNumber: string;
expiryDate: string;
cvv: string;
}
| {
type: "paypal";
email: string;
}
| {
type: "bank_transfer";
accountNumber: string;
routingNumber: string;
};
function processPayment(method: PaymentMethod, amount: number): void {
switch (method.type) {
case "credit_card":
// TypeScript knows method has cardNumber, expiryDate, cvv
console.log(`Charging ${amount} to card ${method.cardNumber}`);
break;
case "paypal":
// TypeScript knows method has email
console.log(`Charging ${amount} to PayPal ${method.email}`);
break;
case "bank_transfer":
// TypeScript knows method has accountNumber, routingNumber
console.log(
`Charging ${amount} via bank transfer ${method.accountNumber}`
);
break;
default:
// Exhaustiveness check
const _exhaustive: never = method;
throw new Error(`Unhandled payment method: ${_exhaustive}`);
}
}
// ✅ Conditional types for flexible APIs
type ResponseData<T> = T extends { id: string }
? { success: true; data: T }
: never;
type User = { id: string; name: string };
type UserResponse = ResponseData<User>; // { success: true; data: User }
// ✅ Extract promise type
type Awaited<T> = T extends Promise<infer U> ? U : T;
type UserPromise = Promise<User>;
type UserType = Awaited<UserPromise>; // User
// ✅ Extract function return type
type ReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never;
function getUser(): User {
return { id: "1", name: "John" };
}
type UserFromFunction = ReturnType<typeof getUser>; // User
// ✅ Make all properties optional
type Partial<T> = {
[P in keyof T]?: T[P];
};
type User = {
id: string;
email: string;
name: string;
};
type PartialUser = Partial<User>;
// { id?: string; email?: string; name?: string }
// ✅ Make all properties readonly
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type ReadonlyUser = Readonly<User>;
// ✅ Pick specific properties
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
type UserPreview = Pick<User, "id" | "name">;
// { id: string; name: string }
// ✅ Omit specific properties
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type UserWithoutId = Omit<User, "id">;
// { email: string; name: string }
// ✅ Type-safe string patterns
type EventName = "user" | "order" | "payment";
type EventAction = "created" | "updated" | "deleted";
type Event = `${EventName}:${EventAction}`;
// 'user:created' | 'user:updated' | 'user:deleted' |
// 'order:created' | 'order:updated' | 'order:deleted' |
// 'payment:created' | 'payment:updated' | 'payment:deleted'
function emitEvent(event: Event): void {
console.log(`Emitting ${event}`);
}
emitEvent("user:created"); // ✅ OK
emitEvent("user:invalid"); // ❌ Type error
// ✅ Function overloads for different input/output types
function getValue(key: "count"): number;
function getValue(key: "name"): string;
function getValue(key: "isActive"): boolean;
function getValue(key: string): unknown {
// Implementation
const values: Record<string, unknown> = {
count: 42,
name: "John",
isActive: true,
};
return values[key];
}
const count = getValue("count"); // Type is number
const name = getValue("name"); // Type is string
const isActive = getValue("isActive"); // Type is boolean
// ✅ Const assertions for literal types
const config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
} as const;
// config.apiUrl type is 'https://api.example.com' (literal)
// config.timeout type is 5000 (literal)
// config is readonly
// ✅ Array as const
const colors = ["red", "green", "blue"] as const;
// Type is readonly ['red', 'green', 'blue']
type Color = (typeof colors)[number];
// Type is 'red' | 'green' | 'blue'
type NonNullable<T> = T extends null | undefined ? never : T;
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>; // string
type Extract<T, U> = T extends U ? T : never;
type Exclude<T, U> = T extends U ? never : T;
type Status = "pending" | "approved" | "rejected" | "cancelled";
type PositiveStatus = Extract<Status, "approved" | "pending">;
// 'approved' | 'pending'
type NegativeStatus = Exclude<Status, "approved" | "pending">;
// 'rejected' | 'cancelled'
type Record<K extends keyof unknown, T> = {
[P in K]: T;
};
type UserRoles = "admin" | "user" | "guest";
type Permissions = Record<UserRoles, string[]>;
// {
// admin: string[];
// user: string[];
// guest: string[];
// }
const permissions: Permissions = {
admin: ["read", "write", "delete"],
user: ["read", "write"],
guest: ["read"],
};
function process(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase(); // value is string here
}
return value.toFixed(2); // value is number here
}
class User {
constructor(public name: string) {}
}
class Admin extends User {
constructor(name: string, public level: number) {
super(name);
}
}
function greet(user: User | Admin): string {
if (user instanceof Admin) {
return `Hello Admin ${user.name}, level ${user.level}`;
}
return `Hello ${user.name}`;
}
type Dog = { bark: () => void };
type Cat = { meow: () => void };
function makeSound(animal: Dog | Cat): void {
if ("bark" in animal) {
animal.bark(); // animal is Dog here
} else {
animal.meow(); // animal is Cat here
}
}
{
"compilerOptions": {
// Strict type checking
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Module resolution
"module": "ESNext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
// Interop
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
// Other
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
// Bun-specific
"types": ["bun-types"],
"target": "ES2022",
"lib": ["ES2022"]
}
}
unknown instead of anyany type@ts-ignore or @ts-expect-error without good reason// ❌ Error
function getName(user: User | null): string {
return user.name; // Error: Object is possibly 'null'
}
// ✅ Solution: Check for null
function getName(user: User | null): string {
if (!user) {
throw new Error("User is null");
}
return user.name; // OK
}
// ✅ Or use optional chaining
function getName(user: User | null): string | undefined {
return user?.name;
}
// ❌ Error
interface User {
id: string;
name: string;
}
const user = {
id: "1",
name: "John",
extra: "field",
};
const typedUser: User = user; // OK (structural typing)
// ✅ Use type annotation or assertion when needed
const exactUser: User = {
id: "1",
name: "John",
// extra: 'field', // Error if uncommented
};
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.