全程类型安全
前后端调用全过程类型安全,调用链路最短、IDE 反馈最快、AI 最友好,简约的 TypeScript 全栈方案,编译时发现错误,全新一代的全栈开发体验
@Controller('api/user')
export class UserController {
@Post(':id/upload')
async uploadAvatar(
@Param('id') userId: string,
@Query('version') version: string,
@UploadedFile() file: Express.Multer.File,
@Body() metadata: { title: string }
) {
return {
success: true,
userId,
version,
filename: file.filename,
metadata,
};
}
}
import { _http } from 'vtzac';
import { UserController } from './backend/user.controller';
const api = _http({
ofetchOptions: {
baseURL: 'http://localhost:3000',
},
}).controller(UserController);
function UploadComponent() {
const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]; // File 类型
if (!file) return;
// 类型安全调用
// 实际请求: POST /api/user/123/upload?version=v2
const result = await api.uploadAvatar(
'123', // @Param('id')
'v2', // @Query('version')
file as unknown as Express.Multer.File, // @UploadedFile()
{ title: '头像' } // @Body()
);
console.log(result._data);
// 打印出: { success: true, userId: '123', version: 'v2', filename: 'avatar.jpg', metadata: { title: '头像' } }
};
return <input type="file" onChange={handleUpload} />;
}