AgentSkillsCN

Typescript Standards

遵循 TypeScript 开发标准,包括包管理器检测(npm/yarn/pnpm/bun)、导出显式返回类型、ESLint/Prettier 代码质量检查、一行 JSDoc 注释,以及自我文档化的代码实践。在处理 TypeScript 或 JavaScript 代码、管理依赖项、运行测试,或确保代码质量时,可运用此技能。当您安装包、编写测试、格式化代码、进行类型检查、添加类型注解、整理导入,或决定是新建文件还是扩展现有文件时,均可使用此技能。适用于任何需要遵守工具链标准与最佳实践的 TypeScript/JavaScript 开发任务。

SKILL.md
--- frontmatter
name: Typescript Standards
description: Apply TypeScript development standards including package manager detection (npm/yarn/pnpm/bun), explicit return types on exports, ESLint/Prettier code quality, one-line JSDoc, and self-documenting code practices. Use this skill when working with TypeScript or JavaScript code, managing dependencies, running tests, or ensuring code quality. Apply when installing packages, writing tests, formatting code, type checking, adding type annotations, organizing imports, or deciding whether to create new files vs. extending existing ones. Use for any TypeScript/JavaScript development task requiring adherence to tooling standards and best practices.

TypeScript Standards

Core Rule: Detect and use the project's package manager. Write self-documenting TypeScript with explicit types on exports.

When to use this skill

  • When installing packages or running scripts in a TypeScript project
  • When writing or modifying TypeScript code
  • When adding type annotations or organizing imports in a TypeScript project
  • When writing tests or running code quality tools in a TypeScript project

Package Manager Detection

CRITICAL: Always detect and use the project's existing package manager. NEVER mix package managers.

Check the project root for lock files:

  • bun.lockb → use bun
  • pnpm-lock.yaml → use pnpm
  • yarn.lock → use yarn
  • package-lock.json → use npm

If no lock file exists, check packageManager field in package.json, or default to npm.

Quick command mapping:

Actionnpmyarnpnpmbun
Install allnpm installyarnpnpm installbun install
Add packagenpm install pkgyarn add pkgpnpm add pkgbun add pkg
Add dev depnpm install -D pkgyarn add -D pkgpnpm add -D pkgbun add -D pkg
Run scriptnpm run scriptyarn scriptpnpm scriptbun script
Execute binarynpx cmdyarn cmdpnpm cmdbunx cmd

Type Annotations

Add explicit return types to all exported functions:

typescript
// Required for exports
export function processOrder(orderId: string, userId: number): Order {
  // implementation
}

// Required for async functions
export async function fetchUser(id: string): Promise<User> {
  // implementation
}

// Optional for internal functions (inference is fine)
function formatPrice(amount: number) {
  return `$${amount.toFixed(2)}`;
}

Prefer interfaces for object shapes, types for unions:

typescript
interface User {
  id: string;
  email: string;
  createdAt: Date;
}

type Status = 'pending' | 'active' | 'suspended';
type Handler = (req: Request, res: Response) => Promise<void>;

Code Style

Write self-documenting code. Minimize comments.

typescript
// BAD - comment explains unclear code
if (u.r === 'admin' || u.r === 'moderator') {

// GOOD - code explains itself
if (user.isAdmin() || user.isModerator()) {

Use concise one-line JSDoc for exported functions:

typescript
/** Calculate discounted price by applying rate. */
export function calculateDiscount(price: number, rate: number): number {
  return price * (1 - rate);
}

Import organization: Node built-ins → External packages → Internal modules → Relative imports

typescript
import { readFile } from 'node:fs/promises';
import express from 'express';
import { User } from '@/models/user';
import { formatPrice } from './utils';

Common Patterns

Use async/await, optional chaining, and nullish coalescing:

typescript
const email = user?.profile?.email ?? 'default@example.com';

async function fetchData(): Promise<Data> {
  const response = await fetch(url);
  return response.json();
}

Prefer node: prefix for built-in modules:

typescript
import { readFile } from 'node:fs/promises';
import path from 'node:path';

Use const assertions for literal types:

typescript
const ROLES = ['admin', 'user', 'guest'] as const;
type Role = typeof ROLES[number]; // 'admin' | 'user' | 'guest'

Don't swallow errors:

typescript
try {
  await process();
} catch (error) {
  logger.error('Processing failed', { error });
  throw error;
}

File Organization

Prefer editing existing files over creating new ones.

Before creating a new file, ask:

  1. Can this fit in an existing module?
  2. Is there a related file to extend?

Naming: kebab-case for files (user-service.ts), .test.ts or .spec.ts for tests.

Verification

Before marking work complete, always run these checks (using the detected package manager):

  1. Format code: Check package.json scripts for format or prettier. Otherwise: prettier --write . or biome format --write .
  2. Lint code: Check package.json scripts for lint. Otherwise: eslint . --fix or biome check --fix .
  3. Type check: Check package.json scripts for typecheck or tsc. Otherwise: tsc --noEmit
  4. Run tests: Check package.json scripts for test

Tip: Look at package.json scripts first — projects often have custom configurations. Use what's already defined.

Then verify:

  • All commands pass without errors
  • Explicit return types on exports
  • Lock file committed (if dependencies changed)