Skip to content

参数绑定

参数装饰器按参数索引绑定,不根据 TypeScript 声明类型绑定。显式名称能保留到压缩构建后,是路径/查询/头字段的可靠选择。

绑定矩阵

parameter(type: ParameterType, name = '') 返回传统方法参数装饰器。ParameterMetadata 保存 type、可选 nameindexPARAMETER_METADATA_KEY 是目标/属性上的元数据 Symbol。

工厂 / ParameterType标量参数对象参数Nullish 行为
path(name = '') / PATH绑定具名路径字段合并可枚举条目,忽略显式 name跳过 null/undefined
query(name = '') / QUERY绑定具名查询字段合并条目跳过 null/undefined
header(name = '') / HEADER设置具名请求头大小写不敏感合并条目整个参数 null/undefined 时跳过,对象字段为 undefined 时删除该头
body() / BODY整个请求正文整个请求正文按原值赋值,再参与 request 合并
request() / REQUEST应为 ParameterRequest最后合并到已解析请求假值变为空请求
attribute(name = '') / ATTRIBUTE具名 Map 条目,跳过 undefined合并记录/Map 条目,null 不增加条目记录合并忽略 null

参数从左到右处理,后绑定优先。body/request 每种只选择一个值,因此最后一个此类参数获胜,并非合并多个 request 参数。普通未注解参数被忽略。

ParameterRequest<BODY> 扩展 FetchRequestInit<BODY>PathCapable。其 path 改变端点路径,替换值应放在 urlParams.path。它可覆盖 method、headers、body、timeout、signal 和原生 Fetch 字段,遵循 mergeRequest 规则(含 nullish 回退)。空字符串参数路径不会覆盖非空端点路径。

替换后的方法只接收实际参数列表,原占位方法的默认参数表达式不会执行。请显式传入默认值,或在 urlParams 元数据中配置。

名称与反射

getParameterNames(func): string[] 解析 Function.toString(),以函数为键在 WeakMap 缓存;解析失败返回空数组,非函数在解析前抛 TypeError。实现使用简单逗号分割并去掉类型/默认值,复杂语法及压缩后的名称不是稳定契约。

getParameterName(target, propertyKey, index, providedName?) 优先返回真值显式名称,再尝试推断,否则 undefined。没有解析名称的标量绑定回退到 param${index}。缺失路径绑定可产生诊断警告,但随后 URL 解析器可能因缺值抛错,不能把警告视为执行成功。

取消与继承元数据

AbortSignalAbortController 参数在装饰器元数据之前识别,即使没有装饰器也有效。多个同类参数最后一个优先;request 参数还能覆盖。signal 会绕过 Fetcher timeout,详见取消

继承参数元数据采用写时复制,装饰重写方法不会修改父类 Map。类绑定遍历继承的字符串命名方法,Symbol 命名和静态方法不在该遍历中。继承/重写端点也应显式填写参数名称。

完整示例

ts
import {
  api,
  post,
  path,
  query,
  body,
  request,
  autoGeneratedError,
  type ParameterRequest,
} from '@ahoo-wang/fetcher-decorator';

type User = { id: string; name: string };
@api('/users')
class Users {
  @post('/{id}')
  update(
    @path('id') id: string,
    @query('notify') notify: boolean,
    @body() value: { name: string },
    @request() options?: ParameterRequest,
    signal?: AbortSignal,
  ): Promise<User> {
    throw autoGeneratedError(id, notify, value, options, signal);
  }
}
const users = new Users();
async function updateUser() {
  const controller = new AbortController();
  return users.update(
    '1',
    true,
    { name: 'Ada' },
    { headers: { 'X-Trace-Id': 'demo' } },
    controller.signal,
  );
}
void updateUser;

公开符号与源码

符号实现
ParameterTypeparameterDecorator.ts:19
ParameterMetadataparameterDecorator.ts:136
PARAMETER_METADATA_KEYparameterDecorator.ts:161
parameterparameterDecorator.ts:199
pathparameterDecorator.ts:265
queryparameterDecorator.ts:297
headerparameterDecorator.ts:329
bodyparameterDecorator.ts:347
ParameterRequestparameterDecorator.ts:359
requestparameterDecorator.ts:379
attributeparameterDecorator.ts:415
getParameterNamesreflection.ts:46
getParameterNamereflection.ts:92

包索引

基于 Apache License 2.0 发布。