You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于动态插件缩小TypeScript推断的泛型类型?

实现路由定义驱动的Context类型缩小方案

完全可以实现,核心是利用TypeScript的泛型、条件类型和映射类型,让server.route方法根据传入的路由定义自动推导对应的Context子集类型,具体方案如下:

1. 定义插件的类型契约

每个插件需要明确自身的路由配置要求和对应的Context注入类型,用通用类型约束插件的类型边界:

// 通用插件类型:关联路由配置与Context注入内容
type Plugin<RouteConfig extends object, ContextAddon extends object> = {
  requiredConfig: RouteConfig;
  injectedContext: ContextAddon;
};

// 示例:认证插件的类型定义
type AuthPlugin = Plugin<{ auth: true }, User<AuthOptions>>;
// 示例:校验插件的类型定义
type ValidationPlugin = Plugin<{ validation: ValidationOptions }, ValidationResult<ValidationOptions>>;

2. 构建路由配置到Context的类型映射

通过条件类型,根据路由定义中包含的插件配置,提取对应的Context注入部分:

// 根据路由定义推导Context类型
type RouteConfigToContext<RouteDef> = 
  // 如果路由包含认证配置,注入User上下文
  RouteDef extends AuthPlugin['requiredConfig'] ? AuthPlugin['injectedContext'] : {} &
  // 如果路由包含校验配置,注入ValidationResult上下文
  RouteDef extends ValidationPlugin['requiredConfig'] ? ValidationPlugin['injectedContext'] : {};

3. 改造server.route方法的泛型定义

让server.route接收路由定义的泛型参数,自动关联对应的Context类型:

interface Server {
  route<RouteDef extends object>(options: {
    config: RouteDef;
    // 这里的ctx类型会根据RouteDef自动缩小
    handler: (ctx: RouteConfigToContext<RouteDef>) => void;
  }): void;
}

4. 多插件场景的批量处理(进阶)

如果插件数量较多,手动编写条件类型效率低,可以用映射类型+联合转交叉的辅助类型批量处理:

// 定义所有插件的配置-Context映射集合
type PluginMap = {
  auth: { config: { auth: true }; context: User<AuthOptions> };
  validation: { config: { validation: ValidationOptions }; context: ValidationResult<ValidationOptions> };
  // 新增插件直接在这里扩展
};

// 提取路由定义匹配的所有Context注入类型
type ExtractMatchedContexts<RouteDef> = {
  [K in keyof PluginMap]: RouteDef extends PluginMap[K]['config'] ? PluginMap[K]['context'] : {};
}[keyof PluginMap];

// 辅助类型:将联合类型转为交叉类型,合并多个Context注入
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 最终的路由到Context的类型映射
type RouteConfigToContext<RouteDef> = UnionToIntersection<ExtractMatchedContexts<RouteDef>>;

效果演示

当传入不同的路由定义时,Context类型会自动缩小:

// 仅带认证配置:ctx类型为User<AuthOptions>
server.route({
  config: { auth: true },
  handler: (ctx) => {
    console.log(ctx.user.id); // 类型安全,无报错
  }
});

// 同时带认证和校验配置:ctx类型为User<AuthOptions> & ValidationResult<ValidationOptions>
server.route({
  config: { auth: true, validation: { schema: userSchema } },
  handler: (ctx) => {
    console.log(ctx.user.id, ctx.validatedData); // 均能正确识别类型
  }
});

内容的提问来源于stack exchange,提问作者robertrosman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:05:04