Add an iOS App Clip target to an Expo app. Use when the user mentions App Clip, AASA, apple-app-site-association, appclips, smart app banner, or wants to ship a lightweight iOS Clip invoked from a URL alongside their parent app.
中文简介正在准备中。当前显示原文说明。
Expert TypeScript engineering with advanced patterns, architectural design, performance optimization, testing strategies, and production-grade code quality. Use when building scalable TypeScript applications, implementing complex type systems, optimizing performance, designing maintainable architectures, or when the user asks for TypeScript engineering excellence, advanced patterns, or professional-grade code practices.
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Apply these principles for production-grade TypeScript:
TypeScript is a language for building maintainable systems at scale. Every design decision should consider:
Use TypeScript's built-in utility types effectively:
// Partial<T> - All properties optional
type UpdateUserDto = Partial<User>;
// Pick<T, K> - Select specific properties
type UserPublic = Pick<User, 'id' | 'name' | 'email'>;
// Omit<T, K> - Exclude specific properties
type UserWithoutPassword = Omit<User, 'password' | 'salt'>;
// Record<K, V> - Map keys to values
type RolePermissions = Record<UserRole, Permission[]>;
// Extract<T, U> - Extract union members matching type
type StringKeys = Extract<keyof User, string>;
// Exclude<T, U> - Exclude union members matching type
type NonMethodKeys = Exclude<keyof User, Function>;
Use conditional types for type-level logic:
// Conditional return types based on input
type ApiResponse<T> = T extends Error
? { error: true; message: string }
: { error: false; data: T };
// Extract promise type
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
// Deep readonly
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
Leverage template literal types for type-safe string manipulation:
// Type-safe API routes
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type ApiRoute = `/api/${string}`;
type FullRoute = `${HttpMethod} ${ApiRoute}`;
// Type-safe CSS classes
type ComponentSize = 'sm' | 'md' | 'lg';
type ComponentVariant = 'primary' | 'secondary' | 'danger';
type ButtonClass = `btn-${ComponentSize}-${ComponentVariant}`;
Prevent primitive type confusion:
// Branded types for type safety
type UserId = string & { readonly __brand: unique symbol };
type ProductId = string & { readonly __brand: unique symbol };
function createUserId(id: string): UserId {
return id as UserId;
}
// Usage prevents mixing up IDs
function fetchUser(id: UserId): Promise<User> {
// Type system prevents passing ProductId
}
Design for testability with explicit dependencies:
interface UserRepository {
findById(id: string): Promise<User | null>;
save(user: User): Promise<void>;
}
interface EmailService {
send(to: string, subject: string, body: string): Promise<void>;
}
class UserService {
constructor(
private readonly userRepo: UserRepository,
private readonly emailService: EmailService
) {}
async registerUser(email: string): Promise<User> {
const user = await this.userRepo.save({ email });
await this.emailService.send(email, 'Welcome', '...');
return user;
}
}
Replace exceptions with explicit error handling:
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
async function fetchUser(id: string): Promise<Result<User, 'NOT_FOUND' | 'NETWORK_ERROR'>> {
try {
const user = await api.get(`/users/${id}`);
return { success: true, data: user };
} catch (error) {
return { success: false, error: 'NOT_FOUND' };
}
}
// Usage forces explicit error handling
const result = await fetchUser('123');
if (result.success) {
console.log(result.data.email);
} else {
console.error(result.error);
}
Abstract data access for flexibility:
interface Repository<T, ID = string> {
findById(id: ID): Promise<T | null>;
findAll(): Promise<T[]>;
save(entity: T): Promise<T>;
delete(id: ID): Promise<void>;
}
class InMemoryUserRepository implements Repository<User> {
private users = new Map<string, User>();
async findById(id: string): Promise<User | null> {
return this.users.get(id) ?? null;
}
// ... other methods
}
// Easy to swap implementations
const userRepo: Repository<User> = new InMemoryUserRepository();
// Later: const userRepo = new PostgresUserRepository();
Minimize bundle size impact:
// Use tree-shaking friendly exports
export { specificFunction } from './utils';
// Avoid: export * from './utils';
// Lazy load heavy dependencies
const loadHeavyLibrary = async () => {
const { HeavyLibrary } = await import('./heavy-library');
return HeavyLibrary;
};
// Use const enums for compile-time inlining
const enum Status {
Active = 1,
Inactive = 2,
}
Optimize hot paths:
// Memoize expensive computations
function memoize<Args extends unknown[], Return>(
fn: (...args: Args) => Return
): (...args: Args) => Return {
const cache = new Map<string, Return>();
return (...args: Args) => {
const key = JSON.stringify(args);
if (!cache.has(key)) {
cache.set(key, fn(...args));
}
return cache.get(key)!;
};
}
// Batch operations
async function batchProcess<T>(
items: T[],
batchSize: number,
processor: (batch: T[]) => Promise<void>
): Promise<void> {
for (let i = 0; i < items.length; i += batchSize) {
await processor(items.slice(i, i + batchSize));
}
}
Define domain-specific error types:
class DomainError extends Error {
constructor(
message: string,
public readonly code: string,
public readonly statusCode: number = 500
) {
super(message);
this.name = this.constructor.name;
}
}
class NotFoundError extends DomainError {
constructor(resource: string) {
super(`${resource} not found`, 'NOT_FOUND', 404);
}
}
class ValidationError extends DomainError {
constructor(message: string, public readonly fields: string[]) {
super(message, 'VALIDATION_ERROR', 400);
}
}
// Type-safe error handling
function handleError(error: unknown): DomainError {
if (error instanceof DomainError) {
return error;
}
return new DomainError('Internal server error', 'INTERNAL_ERROR');
}
Implement graceful degradation:
async function fetchWithRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
delay = 1000
): Promise<Result<T, Error>> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const data = await fn();
return { success: true, data };
} catch (error) {
if (attempt === maxRetries - 1) {
return { success: false, error: error as Error };
}
await new Promise(resolve => setTimeout(resolve, delay * (attempt + 1)));
}
}
return { success: false, error: new Error('Max retries exceeded') };
}
Write code that's easy to test:
// Separate pure functions from side effects
// Pure function - easy to test
function calculateTotal(items: LineItem[]): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
// Side effect - inject dependencies for testing
class OrderService {
constructor(
private readonly taxCalculator: TaxCalculator,
private readonly logger: Logger
) {}
async processOrder(order: Order): Promise<void> {
const tax = this.taxCalculator.calculate(order);
this.logger.info(`Processing order with tax: ${tax}`);
// ... process order
}
}
Create reusable test helpers:
// Test utilities
export function createMockRepository<T>(
initialData: T[] = []
): Repository<T> {
const data = new Map<string, T>();
initialData.forEach(item => {
data.set((item as any).id, item);
});
return {
findById: async (id: string) => data.get(id) ?? null,
findAll: async () => Array.from(data.values()),
save: async (entity: T) => {
const id = (entity as any).id;
data.set(id, entity);
return entity;
},
delete: async (id: string) => {
data.delete(id);
},
};
}
Organize by feature, not by file type:
src/
├── features/
│ ├── users/
│ │ ├── user.entity.ts
│ │ ├── user.repository.ts
│ │ ├── user.service.ts
│ │ ├── user.controller.ts
│ │ └── index.ts
│ └── orders/
│ └── ...
├── shared/
│ ├── types/
│ ├── utils/
│ └── errors/
└── infrastructure/
├── database/
└── http/
Use index files for clean imports:
// features/users/index.ts
export { User } from './user.entity';
export { UserRepository } from './user.repository';
export { UserService } from './user.service';
export type { UserDto, CreateUserDto } from './user.types';
// Usage
import { UserService, User, CreateUserDto } from '@/features/users';
Make configuration errors compile-time errors:
interface AppConfig {
database: {
host: string;
port: number;
};
api: {
baseUrl: string;
timeout: number;
};
}
function loadConfig(): AppConfig {
const config = {
database: {
host: process.env.DB_HOST ?? (() => {
throw new Error('DB_HOST is required');
})(),
port: Number(process.env.DB_PORT ?? 5432),
},
api: {
baseUrl: process.env.API_BASE_URL!,
timeout: Number(process.env.API_TIMEOUT ?? 5000),
},
};
// Type system ensures all required fields are present
return config satisfies AppConfig;
}
Enhance IDE experience with JSDoc:
/**
* Calculates the total price including tax.
*
* @param items - Array of line items with price and quantity
* @param taxRate - Tax rate as a decimal (e.g., 0.08 for 8%)
* @returns Total price including tax
*
* @example
* ```ts
* const total = calculateTotalWithTax(
* [{ price: 10, quantity: 2 }],
* 0.08
* ); // Returns 21.6
* ```
*/
function calculateTotalWithTax(
items: Array<{ price: number; quantity: number }>,
taxRate: number
): number {
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
return subtotal * (1 + taxRate);
}
Use Biome for fast, integrated linting and formatting:
Installation:
npm install --save-dev @biomejs/biome
Configuration (biome.json):
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"useExhaustiveDependencies": "warn"
},
"style": {
"useImportType": "error",
"useConst": "error",
"noParameterAssign": "error"
},
"suspicious": {
"noExplicitAny": "error",
"noArrayIndexKey": "warn",
"noAssignInExpressions": "error"
},
"performance": {
"noDelete": "error"
},
"complexity": {
"noForEach": "off",
"useSimplifiedLogicExpression": "warn"
}
}
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf",
"ignore": ["node_modules", "dist", "build"]
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always"
}
},
"overrides": [
{
"include": ["*.test.ts", "*.spec.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
]
}
Package.json scripts:
{
"scripts": {
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"format": "biome format --write .",
"check": "biome check .",
"check:fix": "biome check --write ."
}
}
Key Benefits:
VS Code Integration:
// .vscode/settings.json
{
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
For detailed Biome configuration and rule customization, see references/biome.md.
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Add an iOS App Clip target to an Expo app. Use when the user mentions App Clip, AASA, apple-app-site-association, appclips, smart app banner, or wants to ship a lightweight iOS Clip invoked from a URL alongside their parent app.
中文简介正在准备中。当前显示原文说明。
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
中文简介正在准备中。当前显示原文说明。
Add Agentation visual feedback toolbar to a Next.js project
中文简介正在准备中。当前显示原文说明。
Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.
中文简介正在准备中。当前显示原文说明。
Derive and implement first-principles audio-coupled haptic and kinetic UI feedback. Use when designing, reviewing, or coding haptics/audio for mobile apps, native iOS/Android, React Native/Expo, SwiftUI, games, detent pickers, toggles, sliders, page curls, scroll gestures, wallet/signature flows, Solana transactions, backend/realtime state changes, confirmations, settlements, and semantic UI events where feedback should follow signal math instead of ad hoc vibration calls.
中文简介正在准备中。当前显示原文说明。
Babysit a GitHub pull request during a user-approved monitoring window by polling review comments, CI checks/workflow runs, and mergeability state. Diagnose failures, retry likely flaky failures up to 3 times, auto-fix/push branch-related issues when appropriate, and report fresh review feedback. Use when the user asks Codex to monitor a PR, watch CI, handle review comments, or keep an eye on failures and feedback on an open PR.
中文简介正在准备中。当前显示原文说明。