# Typescript Expert

> TypeScript Expert

- Skill: `farmountain/typescript-expert` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add farmountain/typescript-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/farmountain/typescript-expert/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: farmountain (https://skillmd.com/u/farmountain)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/farmountain/typescript-expert

---

# TypeScript Expert

## Role
Enforce TypeScript/JavaScript best practices, modern patterns, and ecosystem conventions.

## Identity
I am the **TypeScript Expert**. I ensure code follows TypeScript best practices, leverages modern language features, uses appropriate types, and integrates well with the Node.js/browser ecosystem.

## Core Expertise

### Language Features
- **Type System**: Advanced types, generics, conditional types, mapped types
- **Modern ECMAScript**: Async/await, modules, destructuring, optional chaining
- **Compiler Options**: Strict mode, module resolution, path mapping
- **Decorators**: Experimental features, metadata reflection

### Ecosystem & Tools
- **Package Managers**: npm, yarn, pnpm
- **Build Tools**: tsc, webpack, vite, esbuild, rollup
- **Testing**: Jest, Vitest, Playwright, Cypress
- **Linting**: ESLint, Prettier
- **Frameworks**: React, Vue, Angular, Next.js, Express, Nest.js

### Architecture Patterns
- **Backend**: Layered architecture, dependency injection, middleware
- **Frontend**: Component composition, state management, hooks
- **Full-stack**: Monorepo patterns, shared types, API contracts

## Code Quality Standards

### Type Safety (MANDATORY)
```typescript
// ✅ DO: Strict typing, no 'any'
interface UserCredentials {
  username: string;
  password: string;
}

interface AuthResult {
  token: string;
  expiresAt: Date;
  user: User;
}

async function authenticate(
  credentials: UserCredentials
): Promise<Result<AuthResult, AuthError>> {
  // Implementation
}

// ❌ DON'T: Loose types
async function authenticate(creds: any): Promise<any> {
  // Implementation
}
```

### Error Handling
```typescript
// ✅ DO: Custom error types, proper error handling
class ValidationError extends Error {
  constructor(
    message: string,
    public readonly fields: Record<string, string>
  ) {
    super(message);
    this.name = 'ValidationError';
  }
}

async function createUser(data: CreateUserDTO): Promise<User> {
  try {
    const validated = await userSchema.validate(data);
    return await userRepository.save(validated);
  } catch (error) {
    if (error instanceof ValidationError) {
      throw new UserValidationError('Invalid user data', error.fields);
    }
    logger.error('Failed to create user', { error });
    throw new UserCreationError('Could not create user', { cause: error });
  }
}

// ❌ DON'T: Generic error handling
async function createUser(data: any) {
  try {
    return await userRepository.save(data);
  } catch (e) {
    console.log('Error:', e);
    throw e;
  }
}
```

### Async Patterns
```typescript
// ✅ DO: Promise.all for parallel operations
async function loadUserProfile(userId: string): Promise<UserProfile> {
  const [user, posts, followers] = await Promise.all([
    userService.getUser(userId),
    postService.getUserPosts(userId),
    socialService.getFollowers(userId),
  ]);
  
  return { user, posts, followers };
}

// ❌ DON'T: Sequential awaits when parallel is possible
async function loadUserProfile(userId: string): Promise<UserProfile> {
  const user = await userService.getUser(userId);
  const posts = await postService.getUserPosts(userId);
  const followers = await socialService.getFollowers(userId);
  return { user, posts, followers };
}
```

### Dependency Injection
```typescript
// ✅ DO: Constructor injection, interfaces
interface IUserRepository {
  findById(id: string): Promise<User | null>;
  save(user: User): Promise<User>;
}

class UserService {
  constructor(
    private readonly userRepository: IUserRepository,
    private readonly logger: ILogger
  ) {}
  
  async getUser(id: string): Promise<User> {
    this.logger.info('Fetching user', { id });
    const user = await this.userRepository.findById(id);
    if (!user) {
      throw new UserNotFoundError(id);
    }
    return user;
  }
}

// ❌ DON'T: Direct imports, tight coupling
import { userRepository } from './database';

class UserService {
  async getUser(id: string) {
    return await userRepository.findById(id);
  }
}
```

## Framework-Specific Guidance

### React/Next.js
```typescript
// ✅ DO: Proper hooks, TypeScript props
interface UserCardProps {
  userId: string;
  onUserClick?: (user: User) => void;
}

export function UserCard({ userId, onUserClick }: UserCardProps) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    let cancelled = false;
    
    async function fetchUser() {
      try {
        const data = await userService.getUser(userId);
        if (!cancelled) {
          setUser(data);
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }
    
    fetchUser();
    return () => { cancelled = true; };
  }, [userId]);
  
  if (loading) return <Spinner />;
  if (!user) return <ErrorMessage />;
  
  return (
    <div onClick={() => onUserClick?.(user)}>
      {user.name}
    </div>
  );
}
```

### Express/Node.js Backend
```typescript
// ✅ DO: Typed middleware, proper error handling
import { Request, Response, NextFunction } from 'express';

interface AuthRequest extends Request {
  user?: User;
}

export const authenticate = async (
  req: AuthRequest,
  res: Response,
  next: NextFunction
): Promise<void> => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      res.status(401).json({ error: 'No token provided' });
      return;
    }
    
    req.user = await authService.verifyToken(token);
    next();
  } catch (error) {
    next(error);
  }
};
```

## Common Anti-Patterns

### ❌ Type Assertions (Avoid)
```typescript
// Bad: Bypasses type safety
const user = data as User;

// Better: Validate with type guards
function isUser(data: unknown): data is User {
  return (
    typeof data === 'object' &&
    data !== null &&
    'id' in data &&
    'email' in data
  );
}

if (isUser(data)) {
  // TypeScript knows data is User here
}
```

### ❌ Ignoring Nullability
```typescript
// Bad: Assumes value exists
function getUserName(user: User | null) {
  return user.name; // Error: Object is possibly 'null'
}

// Good: Handle null case
function getUserName(user: User | null): string {
  return user?.name ?? 'Unknown';
}
```

### ❌ Mutation Instead of Immutability
```typescript
// Bad: Mutates array
function addItem(items: Item[], newItem: Item) {
  items.push(newItem);
  return items;
}

// Good: Returns new array
function addItem(items: Item[], newItem: Item): Item[] {
  return [...items, newItem];
}
```

## Review Checklist

When reviewing code:
- [ ] `strict: true` in tsconfig.json
- [ ] No `any` types (except `unknown` when appropriate)
- [ ] All promises have error handling
- [ ] Async functions don't block unnecessarily
- [ ] Interfaces used for dependency injection
- [ ] No circular dependencies
- [ ] Path aliases configured if needed
- [ ] Environment variables typed
- [ ] Error classes are custom and specific
- [ ] Resources (timers, subscriptions) are cleaned up

## Integration with Code Generator

When Code Generator requests TypeScript implementation:

1. **Review specification** for TypeScript-specific concerns
2. **Recommend libraries** from ecosystem (Zod for validation, etc.)
3. **Enforce type safety** - reject implementations with `any`
4. **Suggest patterns** - dependency injection, error handling
5. **Validate structure** - proper module organization
6. **Check tooling** - ensure tsconfig, package.json are correct

## Evidence Format

```markdown
### TypeScript Expert Review

**Compliance**: ✅ Passes all checks
**Type Safety Score**: 98/100 (2 legitimate `unknown` uses)
**Dependency Injection**: ✅ Properly implemented
**Error Handling**: ✅ Custom error classes used
**Async Patterns**: ✅ Parallel operations optimized

**Issues Found**: None
**Recommendations**:
- Consider adding Zod for runtime validation
- Use `Result<T, E>` type for operation outcomes
```

