cursor-init/docs/api-type-usage-examples.md
expressgy a23d336ebd refactor: 重构项目架构并标准化开发规范
- 重构项目结构:controllers/services -> modules模块化组织

- 新增Drizzle ORM集成和数据库schema定义

- 添加完整的开发规范文档(.cursor/rules/)

- 重新组织插件结构为子目录方式

- 新增用户模块和示例代码

- 更新类型定义并移除试验性代码

- 添加API文档和JWT使用示例

关联任务计划文档
2025-06-30 01:25:17 +08:00

4.4 KiB
Raw Blame History

API Schema 类型使用指南

1. Schema 转 TypeScript 类型

.schema.ts 文件中定义并导出类型:

// example.schema.ts
import { t, type Static } from 'elysia';

// Schema 定义
export const GetUserByUsernameSchema = t.Object({
    username: t.String({
        minLength: 2,
        maxLength: 50,
        description: '用户名',
    }),
});

// 从 Schema 推断类型
export type GetUserByUsernameParams = Static<typeof GetUserByUsernameSchema>;

2. 在 Service 中使用类型

// example.service.ts
import type { GetUserByUsernameParams, UserInfo } from './example.schema';

export class ExampleService {
    // 使用类型注解参数
    async getUserByUsername(params: GetUserByUsernameParams): Promise<UserInfo> {
        const { username } = params; // TypeScript 会自动推断类型
        
        // 业务逻辑...
        return userResult;
    }
    
    // 或者直接使用解构参数
    async getUserByUsername2({ username }: GetUserByUsernameParams): Promise<UserInfo> {
        // 业务逻辑...
        return userResult;
    }
}

3. 在 Controller 中使用类型

// example.controller.ts
import type { GetUserByUsernameParams, UserInfo } from './example.schema';
import { GetUserByUsernameSchema } from './example.schema';

export const controller = new Elysia()
    .get(
        '/user/:username',
        async ({ params }) => {
            // params 自动推断为 GetUserByUsernameParams 类型
            const userInfo: UserInfo = await service.getUserByUsername(params);
            return successResponse(userInfo);
        },
        {
            // 使用 Schema 进行运行时验证
            params: GetUserByUsernameSchema,
        }
    );

4. 在测试中使用类型

// example.test.ts
import type { GetUserByUsernameParams, UserInfo } from './example.schema';

describe('用户查询测试', () => {
    it('应该正确处理参数类型', () => {
        // 类型安全的测试数据
        const validParams: GetUserByUsernameParams = {
            username: 'testuser'
        };
        
        const invalidParams = {
            username: 'a' // TypeScript 会提示这可能不符合验证规则
        };
    });
});

5. 工具函数中使用类型

// utils/validators.ts
import type { GetUserByUsernameParams } from '../modules/sample/example.schema';

// 类型安全的验证函数
export function validateUsername(params: GetUserByUsernameParams): boolean {
    return params.username.length >= 2 && params.username.length <= 50;
}

// 类型安全的格式化函数
export function formatUserQuery(params: GetUserByUsernameParams): string {
    return `查询用户: ${params.username}`;
}

6. 响应类型使用示例

// example.response.ts
import { t, type Static } from 'elysia';
import { UserInfoSchema } from './example.schema';

export const GetUserSuccessResponse = t.Object({
    code: t.Literal(0),
    message: t.String(),
    data: UserInfoSchema,
});

// 导出响应类型
export type GetUserSuccessResponseType = Static<typeof GetUserSuccessResponse>;

7. 完整的类型流转示例

// 完整的类型安全流程
import type { 
    GetUserByUsernameParams, 
    UserInfo 
} from './example.schema';

// Service 层
class UserService {
    async getUser(params: GetUserByUsernameParams): Promise<UserInfo> {
        // params.username 有完整的类型提示
        // 返回值必须符合 UserInfo 类型
    }
}

// Controller 层  
const controller = new Elysia()
    .get('/user/:username', async ({ params }) => {
        // params 自动推断类型
        const user = await userService.getUser(params);
        // user 自动推断为 UserInfo 类型
        return { code: 0, message: '成功', data: user };
    }, {
        params: GetUserByUsernameSchema, // 运行时验证
    });

💡 最佳实践

  1. 总是导出类型:每个 Schema 都应该导出对应的 TypeScript 类型
  2. 类型注解:在 Service 方法中明确使用类型注解
  3. 一致命名:类型名应该与 Schema 名保持一致的命名规范
  4. 分离关注点Schema 用于运行时验证Type 用于编译时类型检查