Decorator 参考
使用 TypeScript 传统类、方法、参数装饰器声明 Fetcher 服务。
安装与运行时
sh
pnpm add @ahoo-wang/fetcher-decorator @ahoo-wang/fetcher消费项目需要启用旧版 TypeScript 装饰器:experimentalDecorators: true、emitDecoratorMetadata: true。reflect-metadata 是包自身导入的普通依赖,会自动安装。
5.0.0 为消费者声明 Node >=18.20.8。仓库开发另要求 Node >=20.20.2 / pnpm 10.34.5。所用功能依赖的浏览器/运行时 API 也必须存在,engine 范围不代表每个 Web API(如 Response.bytes)均可用。
选择入口
手写服务使用 @api 和方法装饰器;固定参数使用 @path/@query/@body,每次调用的传输选项使用 @request。服务专属的 exchange 处理放在生命周期钩子,共享传输策略放在 Fetcher 拦截器。生成服务也遵循这套运行时契约。
选择专题
| 专题 | 用途 |
|---|---|
| 服务与端点 | 使用 TypeScript 传统装饰器把服务方法替换成 Fetcher 请求。启用 experimentalDecorators、emitDecoratorMetadata,与本包 tsconfig 一致;stage-3 装饰器不支持此参数装饰器契约。包自身会导入 reflect-metadata。 |
| 参数绑定 | 参数装饰器按参数索引绑定,不根据 TypeScript 声明类型绑定。显式名称能保留到压缩构建后,是路径/查询/头字段的可靠选择。 |
| 元数据与执行生命周期 | 每次装饰方法调用解析新的 exchange,同时复用实例级、方法级执行器。钩子运行在服务实例上;并发调用可能重叠时,不要把请求专属可变状态存在该实例上。 |
最小完整示例
ts
import { Fetcher } from '@ahoo-wang/fetcher';
import {
api,
get,
path,
autoGeneratedError,
} from '@ahoo-wang/fetcher-decorator';
type User = { id: string; name: string };
const client = new Fetcher({
baseURL: 'https://api.example.com',
timeout: 3000,
});
@api('/users', { fetcher: client })
class Users {
@get('/{id}')
find(@path('id') id: string): Promise<User> {
throw autoGeneratedError(id);
}
}
const users = new Users();
// Requires a service returning JSON at https://api.example.com/users/1.
async function loadUser() {
return await users.find('1');
}
void loadUser;