Decorator reference
Legacy TypeScript class, method, and parameter decorators for declarative Fetcher services.
Installation and runtime
pnpm add @ahoo-wang/fetcher-decorator @ahoo-wang/fetcherEnable legacy TypeScript decorators in the consuming project: experimentalDecorators: true and emitDecoratorMetadata: true. reflect-metadata is a regular dependency imported by the package; it is installed automatically.
Version 5.0.0 declares Node >=18.20.8 for consumers. Repository development has a separate Node >=20.20.2 / pnpm 10.34.5 requirement. Browser/runtime APIs used by a feature must also exist; the engine range is not a promise that every Web API (for example Response.bytes) is available.
Choose an entry point
Use @api plus method decorators for a hand-written service. Use @path/@query/@body for stable arguments and @request for per-call transport options. Use lifecycle hooks for service-specific exchange work; shared transport policy belongs in Fetcher interceptors. Generated services use the same runtime contract.
Choose a topic
| Topic | Use it for |
|---|---|
| Services and endpoints | Use legacy TypeScript decorators to replace service methods with Fetcher requests. Enable experimentalDecorators and emitDecoratorMetadata (matching this package's tsconfig); stage-3 decorators do not support this parameter-decorator contract. The package imports reflect-metadata itself. |
| Parameter binding | Parameter decorators bind arguments by index, not by their declared TypeScript type. Explicit names survive minification and are the reliable choice for path/query/header fields. |
| Metadata and execution lifecycle | Decorated methods resolve a fresh exchange for each call while reusing a per-instance, per-method executor. Hooks run on the service instance, so avoid storing mutable per-request state on that instance when calls can overlap. |
Minimal complete example
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;