express-typescript by mindrally/skills
npx skills add https://github.com/mindrally/skills --skill express-typescript您是一位精通 Express.js 和 TypeScript 开发的专家,在构建可扩展、可维护的 API 方面拥有深厚的知识。
any 类型 - 应创建必要的类型isLoading、hasError、canDelete广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
readonlysrc/
routes/
{resource}/
index.ts
controller.ts
validators.ts
middleware/
auth.ts
errorHandler.ts
requestLogger.ts
validateRequest.ts
services/
{domain}Service.ts
models/
{entity}.ts
types/
express.d.ts
index.ts
utils/
config/
app.ts
server.ts
import express, { Express } from 'express';
import helmet from 'helmet';
import cors from 'cors';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/requestLogger';
import routes from './routes';
const createApp = (): Express => {
const app = express();
// 安全中间件
app.use(helmet());
app.use(cors());
// 请求体解析
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 请求日志记录
app.use(requestLogger);
// 路由
app.use('/api', routes);
// 错误处理(必须在最后)
app.use(errorHandler);
return app;
};
export default createApp;
使用中间件处理横切关注点
按执行顺序链式调用中间件
在专用的错误处理中间件中处理错误
import { Request, Response, NextFunction } from 'express';
// 请求日志记录中间件 const requestLogger = (req: Request, res: Response, next: NextFunction): void => { const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
console.log(${req.method} ${req.path} ${res.statusCode} ${duration}ms);
});
next(); };
// 身份验证中间件 const authenticate = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const token = req.headers.authorization?.split(' ')[1];
if (!token) {
res.status(401).json({ error: '未提供令牌' });
return;
}
const user = await verifyToken(token);
req.user = user;
next();
} catch (error) { res.status(401).json({ error: '无效令牌' }); } };
按资源组织路由
使用 Router 进行模块化路由定义
在适当的层级应用中间件
import { Router } from 'express'; import { authenticate } from '../middleware/auth'; import { validateRequest } from '../middleware/validateRequest'; import { createUserSchema, updateUserSchema } from './validators'; import * as controller from './controller';
const router = Router();
router.get('/', controller.listUsers); router.get('/:id', controller.getUser); router.post('/', validateRequest(createUserSchema), controller.createUser); router.put('/:id', authenticate, validateRequest(updateUserSchema), controller.updateUser); router.delete('/:id', authenticate, controller.deleteUser);
export default router;
验证所有传入的请求
使用 Zod 进行模式定义和验证
创建可重用的验证中间件
import { z } from 'zod'; import { Request, Response, NextFunction } from 'express';
const createUserSchema = z.object({ body: z.object({ name: z.string().min(1), email: z.string().email(), password: z.string().min(8), }), });
const validateRequest = (schema: z.ZodSchema) => { return async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { await schema.parseAsync({ body: req.body, query: req.query, params: req.params, }); next(); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ error: '验证失败', details: error.errors, }); return; } next(error); } }; };
创建自定义错误类
使用集中式错误处理中间件
返回一致的错误响应
class AppError extends Error { constructor( public statusCode: number, public message: string, public code: string = 'INTERNAL_ERROR' ) { super(message); this.name = 'AppError'; } }
class NotFoundError extends AppError {
constructor(resource: string) {
super(404, ${resource} 未找到, 'NOT_FOUND');
}
}
// 错误处理中间件 const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction): void => { if (err instanceof AppError) { res.status(err.statusCode).json({ error: err.code, message: err.message, }); return; }
console.error(err); res.status(500).json({ error: 'INTERNAL_ERROR', message: '发生意外错误', }); };
为自定义属性扩展 Express 类型:
// types/express.d.ts
import { User } from '../models/User';
declare global {
namespace Express {
interface Request {
user?: User;
requestId?: string;
}
}
}
使用 helmet 设置安全头
实现速率限制
对用户输入进行清理
在生产环境中使用 HTTPS
正确实现 CORS
import helmet from 'helmet'; import rateLimit from 'express-rate-limit';
app.use(helmet());
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 分钟 max: 100, // 每个 IP 在 windowMs 内限制 100 个请求 });
app.use('/api', limiter);
使用 Jest 和 supertest 进行集成测试
隔离测试中间件
模拟外部依赖
import request from 'supertest'; import createApp from '../app';
describe('用户 API', () => { const app = createApp();
it('应该创建一个用户', async () => { const response = await request(app) .post('/api/users') .send({ name: 'John', email: 'john@example.com', password: 'password123' }) .expect(201);
expect(response.body).toHaveProperty('id');
expect(response.body.name).toBe('John');
}); });
每周安装量
185
代码仓库
GitHub 星标数
42
首次出现
Jan 25, 2026
安全审计
安装于
gemini-cli167
opencode167
codex160
github-copilot158
amp153
kimi-cli151
You are an expert in Express.js and TypeScript development with deep knowledge of building scalable, maintainable APIs.
any type - create necessary types insteadisLoading, hasError, canDeletereadonly for immutable propertiessrc/
routes/
{resource}/
index.ts
controller.ts
validators.ts
middleware/
auth.ts
errorHandler.ts
requestLogger.ts
validateRequest.ts
services/
{domain}Service.ts
models/
{entity}.ts
types/
express.d.ts
index.ts
utils/
config/
app.ts
server.ts
import express, { Express } from 'express';
import helmet from 'helmet';
import cors from 'cors';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/requestLogger';
import routes from './routes';
const createApp = (): Express => {
const app = express();
// Security middleware
app.use(helmet());
app.use(cors());
// Body parsing
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Request logging
app.use(requestLogger);
// Routes
app.use('/api', routes);
// Error handling (must be last)
app.use(errorHandler);
return app;
};
export default createApp;
Use middleware for cross-cutting concerns
Chain middleware in order of execution
Handle errors in dedicated error middleware
import { Request, Response, NextFunction } from 'express';
// Request logging middleware const requestLogger = (req: Request, res: Response, next: NextFunction): void => { const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
console.log(${req.method} ${req.path} ${res.statusCode} ${duration}ms);
});
next(); };
// Authentication middleware const authenticate = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const token = req.headers.authorization?.split(' ')[1];
if (!token) {
res.status(401).json({ error: 'No token provided' });
return;
}
const user = await verifyToken(token);
req.user = user;
next();
} catch (error) { res.status(401).json({ error: 'Invalid token' }); } };
Organize routes by resource
Use Router for modular route definitions
Apply middleware at appropriate levels
import { Router } from 'express'; import { authenticate } from '../middleware/auth'; import { validateRequest } from '../middleware/validateRequest'; import { createUserSchema, updateUserSchema } from './validators'; import * as controller from './controller';
const router = Router();
router.get('/', controller.listUsers); router.get('/:id', controller.getUser); router.post('/', validateRequest(createUserSchema), controller.createUser); router.put('/:id', authenticate, validateRequest(updateUserSchema), controller.updateUser); router.delete('/:id', authenticate, controller.deleteUser);
export default router;
Validate all incoming requests
Use Zod for schema definition and validation
Create reusable validation middleware
import { z } from 'zod'; import { Request, Response, NextFunction } from 'express';
const createUserSchema = z.object({ body: z.object({ name: z.string().min(1), email: z.string().email(), password: z.string().min(8), }), });
const validateRequest = (schema: z.ZodSchema) => { return async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { await schema.parseAsync({ body: req.body, query: req.query, params: req.params, }); next(); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ error: 'Validation failed', details: error.errors, }); return; } next(error); } }; };
Create custom error classes
Use centralized error handler middleware
Return consistent error responses
class AppError extends Error { constructor( public statusCode: number, public message: string, public code: string = 'INTERNAL_ERROR' ) { super(message); this.name = 'AppError'; } }
class NotFoundError extends AppError {
constructor(resource: string) {
super(404, ${resource} not found, 'NOT_FOUND');
}
}
// Error handler middleware const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction): void => { if (err instanceof AppError) { res.status(err.statusCode).json({ error: err.code, message: err.message, }); return; }
console.error(err); res.status(500).json({ error: 'INTERNAL_ERROR', message: 'An unexpected error occurred', }); };
Extend Express types for custom properties:
// types/express.d.ts
import { User } from '../models/User';
declare global {
namespace Express {
interface Request {
user?: User;
requestId?: string;
}
}
}
Use helmet for security headers
Implement rate limiting
Sanitize user inputs
Use HTTPS in production
Implement CORS properly
import helmet from 'helmet'; import rateLimit from 'express-rate-limit';
app.use(helmet());
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // limit each IP to 100 requests per windowMs });
app.use('/api', limiter);
Use Jest with supertest for integration tests
Test middleware in isolation
Mock external dependencies
import request from 'supertest'; import createApp from '../app';
describe('Users API', () => { const app = createApp();
it('should create a user', async () => { const response = await request(app) .post('/api/users') .send({ name: 'John', email: 'john@example.com', password: 'password123' }) .expect(201);
expect(response.body).toHaveProperty('id');
expect(response.body.name).toBe('John');
}); });
Weekly Installs
185
Repository
GitHub Stars
42
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli167
opencode167
codex160
github-copilot158
amp153
kimi-cli151
lark-cli 共享规则:飞书资源操作指南与权限配置详解
39,000 周安装