Use this skill when working with TypeScript code, type definitions, interfaces, generics, or async patterns.
Provides TypeScript best practices for type safety, async patterns, and null handling.
/plugin marketplace add https://www.claudepluginhub.com/api/plugins/rbarcante-conductor/marketplace.json/plugin install rbarcante-conductor@cpd-rbarcante-conductorThis skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdmanifest.jsonpatterns/async-patterns.mdpatterns/null-handling.mdpatterns/type-safety.mdGuidance for writing type-safe, maintainable TypeScript code. Covers type safety fundamentals, async/await patterns, and null handling strategies.
strict: true in tsconfig.jsonreadonly and const where possible// Good - interfaces are more extensible
interface User {
id: string;
name: string;
email: string;
}
// Use type for unions, intersections, mapped types
type UserRole = 'admin' | 'user' | 'guest';
type UserWithRole = User & { role: UserRole };
// Good - exhaustive pattern matching
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function handleResult<T>(result: Result<T>) {
if (result.success) {
return result.data; // TypeScript knows data exists
}
throw result.error; // TypeScript knows error exists
}
any - Use unknown Instead// Bad
function processData(data: any) {
return data.value; // No type safety
}
// Good
function processData(data: unknown) {
if (isValidData(data)) {
return data.value; // Type narrowed via guard
}
throw new Error('Invalid data');
}
function isValidData(data: unknown): data is { value: string } {
return typeof data === 'object' && data !== null && 'value' in data;
}
// Good - constrained generics
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Good - default type parameters
interface Repository<T extends { id: string } = { id: string }> {
findById(id: string): Promise<T | null>;
save(entity: T): Promise<T>;
}
// Good
async function fetchUser(id: string): Promise<User> {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Failed to fetch user:', error);
throw error;
}
}
// Good - parallel execution
async function fetchUserData(userId: string) {
const [user, posts, comments] = await Promise.all([
fetchUser(userId),
fetchUserPosts(userId),
fetchUserComments(userId),
]);
return { user, posts, comments };
}
// Good - explicit return type
async function createUser(data: CreateUserDTO): Promise<User> {
const user = await db.users.create(data);
return user;
}
// Good - handle errors with Result type
async function safeCreateUser(data: CreateUserDTO): Promise<Result<User>> {
try {
const user = await db.users.create(data);
return { success: true, data: user };
} catch (error) {
return { success: false, error: error as Error };
}
}
// Good
const userName = user?.profile?.name ?? 'Anonymous';
const config = options?.timeout ?? DEFAULT_TIMEOUT;
// Avoid
const userName = user && user.profile && user.profile.name || 'Anonymous';
// OK when you've verified externally
const element = document.getElementById('root')!;
// Better - explicit check
const element = document.getElementById('root');
if (!element) {
throw new Error('Root element not found');
}
// Good - type guard function
function isDefined<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
// Usage
const values = [1, null, 2, undefined, 3];
const defined = values.filter(isDefined); // number[]
undefined Over null for Optional// Good - consistent with optional properties
interface Options {
timeout?: number; // undefined when not set
retries?: number;
}
// Avoid mixing null and undefined
interface Options {
timeout: number | null; // Inconsistent
retries?: number;
}
// Make all properties optional
type PartialUser = Partial<User>;
// Make all properties required
type RequiredUser = Required<User>;
// Pick specific properties
type UserCredentials = Pick<User, 'email' | 'password'>;
// Omit specific properties
type PublicUser = Omit<User, 'password'>;
// Make properties readonly
type ImmutableUser = Readonly<User>;
// Record for object maps
type UserCache = Record<string, User>;
type AllRoles = 'admin' | 'user' | 'guest' | 'superadmin';
type AdminRoles = Extract<AllRoles, 'admin' | 'superadmin'>; // 'admin' | 'superadmin'
type NonAdminRoles = Exclude<AllRoles, 'admin' | 'superadmin'>; // 'user' | 'guest'
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true
}
}
strict: true enabled in tsconfig.jsonany types without documented justificationunknown instead of any for unknown dataActivates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
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.