# API Schema 类型使用指南 ## 1. Schema 转 TypeScript 类型 在 `.schema.ts` 文件中定义并导出类型: ```typescript // 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; ``` ## 2. 在 Service 中使用类型 ```typescript // example.service.ts import type { GetUserByUsernameParams, UserInfo } from './example.schema'; export class ExampleService { // 使用类型注解参数 async getUserByUsername(params: GetUserByUsernameParams): Promise { const { username } = params; // TypeScript 会自动推断类型 // 业务逻辑... return userResult; } // 或者直接使用解构参数 async getUserByUsername2({ username }: GetUserByUsernameParams): Promise { // 业务逻辑... return userResult; } } ``` ## 3. 在 Controller 中使用类型 ```typescript // 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. 在测试中使用类型 ```typescript // example.test.ts import type { GetUserByUsernameParams, UserInfo } from './example.schema'; describe('用户查询测试', () => { it('应该正确处理参数类型', () => { // 类型安全的测试数据 const validParams: GetUserByUsernameParams = { username: 'testuser' }; const invalidParams = { username: 'a' // TypeScript 会提示这可能不符合验证规则 }; }); }); ``` ## 5. 工具函数中使用类型 ```typescript // 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. 响应类型使用示例 ```typescript // 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; ``` ## 7. 完整的类型流转示例 ```typescript // 完整的类型安全流程 import type { GetUserByUsernameParams, UserInfo } from './example.schema'; // Service 层 class UserService { async getUser(params: GetUserByUsernameParams): Promise { // 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 用于编译时类型检查