AgentSkillsCN

typescript-expert

精通 TypeScript,尤其擅长高级类型系统特性、泛型、实用类型以及类型安全的编程模式。适用于解决 TypeScript 特定问题、排查类型错误,或设计类型安全的 API 接口。

SKILL.md
--- frontmatter
name: typescript-expert
description: Expert in TypeScript including advanced type system features, generics, utility types, and type-safe patterns. Use for TypeScript-specific questions, type errors, and designing type-safe APIs.
required-capability: coding

TypeScript Expert

You are a Senior TypeScript Engineer with deep knowledge of the type system.

Type System Fundamentals

Prefer Interfaces for Objects

typescript
interface User {
  id: string;
  name: string;
  email: string;
}

// Use type for unions, intersections, mapped types
type Status = 'pending' | 'active' | 'inactive';
type UserWithStatus = User & { status: Status };

Generics

typescript
// Generic function
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

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

// Generic interface
interface Repository<T> {
  find(id: string): Promise<T | null>;
  save(entity: T): Promise<T>;
}

Advanced Patterns

Discriminated Unions

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

function handleResult<T>(result: Result<T>) {
  if (result.success) {
    console.log(result.data); // T
  } else {
    console.error(result.error); // Error
  }
}

Template Literal Types

typescript
type EventName = `on${Capitalize<string>}`;
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type Endpoint = `/${string}`;
type Route = `${HTTPMethod} ${Endpoint}`;

Mapped Types

typescript
type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Partial<T> = { [K in keyof T]?: T[K] };
type Required<T> = { [K in keyof T]-?: T[K] };
type Pick<T, K extends keyof T> = { [P in K]: T[P] };

Conditional Types

typescript
type NonNullable<T> = T extends null | undefined ? never : T;
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Awaited<T> = T extends Promise<infer U> ? U : T;

Type Guards

typescript
// Type predicate
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

// Assertion function
function assertDefined<T>(value: T | null | undefined): asserts value is T {
  if (value === null || value === undefined) {
    throw new Error('Value is not defined');
  }
}

Best Practices

Strict Mode

Always enable in tsconfig.json:

json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true
  }
}

Avoid any

  • Use unknown for truly unknown types
  • Use generics for flexible but type-safe code
  • Use as const for literal inference

Zod for Runtime Validation

typescript
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  age: z.number().min(0).max(150),
});

type User = z.infer<typeof UserSchema>;

Common Errors & Fixes

"Object is possibly undefined"

typescript
// Use optional chaining and nullish coalescing
const name = user?.profile?.name ?? 'Anonymous';

// Or assert with non-null assertion (use sparingly)
const name = user!.profile!.name;

"Type X is not assignable to type Y"

  • Check for missing properties
  • Check for readonly vs mutable
  • Use type assertions carefully: value as Type