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

TypeScript如何基于构造传入的参数解析器生成对应类型约束?

解法

你可以通过TS的映射类型和类型推断实现需求,完整的类型定义如下:

class QueryParamHandler<T> {
    parse(v: string): T { throw new Error("未实现") }
    stringify(v: T): string { throw new Error("未实现") }
}

// 基础类型解析器实例定义
const stringParser: QueryParamHandler<string> = new QueryParamHandler();
const numberParser: QueryParamHandler<number> = new QueryParamHandler();
const booleanParser: QueryParamHandler<boolean> = new QueryParamHandler();
const dateParser: QueryParamHandler<Date> = new QueryParamHandler();

// 可复用的类型提取别名,也可以直接写在方法入参/返回值位置
type ExtractHandlerTypes<TP extends Record<string, QueryParamHandler<any>>> = Partial<{
    [K in keyof TP]: TP[K] extends QueryParamHandler<infer T> ? T : never
}>

// 核心MyCoolHandler实现
class MyCoolHandler<TP extends Record<string, QueryParamHandler<any>>> {
    constructor(private handlers: TP) {}

    parse(query: string): ExtractHandlerTypes<TP> {
        // 这里写你的解析逻辑
        return {} as any
    }

    stringify(vals: ExtractHandlerTypes<TP>): string {
        // 这里写你的序列化逻辑
        return ''
    }
}

效果验证

和你期望的运行效果完全匹配:

const handler = new MyCoolHandler({ str: stringParser, from: dateParser });
handler.stringify({});             // 正常通过
handler.stringify({ str: 'qqq' }); // 正常通过
handler.stringify({ numb: 3 });    // TS报错:对象字面量只能指定已知属性,"numb" 不在类型中
handler.stringify({ from: 'qq' }); // TS报错:类型"string"不能分配给类型"Date"

const params = handler.parse('str=&from=2021-09-07')
console.log(params.str)   // 正常读取,类型为string | undefined
console.log(params.numb)  // TS报错:类型上不存在属性"numb"

实现逻辑说明

  1. 给MyCoolHandler定义泛型参数TP,约束为键是字符串、值是QueryParamHandler实例的对象,用来承接构造函数传入的解析器集合
  2. 用infer关键字推断每个QueryParamHandler对应的泛型参数类型,搭配映射类型生成和传入解析器键名一一对应的对象类型
  3. 用Partial工具类型把所有属性设为可选,满足字段允许为undefined的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:27:01