如何根据使用情况解析TypeScript类型?动态键类型推断方案咨询
解决方案
原生TypeScript变通方案(无需插件)
如果能接受链式调用的初始化方式,可以通过泛型累积类型实现需求。核心思路是让setSmth返回一个带有更新后类型的实例,TypeScript会自动推导累积的键值类型:
class TypedStore<T extends Record<string, unknown> = {}> { private store: T = {} as T; setSmth<K extends string, V>(key: K, value: V): TypedStore<T & Record<K, V>> { (this.store as any)[key] = value; return this as TypedStore<T & Record<K, V>>; } getSmth<K extends keyof T>(key: K): T[K] { return this.store[key]; } } // 链式调用初始化,类型自动累积 const obj = new TypedStore() .setSmth('key1', 123) .setSmth('key2', true) .setSmth('another key', () => {}); obj.getSmth('key1'); // 类型推断为number obj.getSmth('key2'); // 类型推断为boolean obj.getSmth('another key'); // 类型推断为() => void
但这种方案有局限:如果setSmth调用分散在应用不同位置(非链式),原生TypeScript的静态类型系统无法追踪跨代码块的类型变化,因为TS编译时无法关联分散的运行时赋值操作。
TSC插件/转换器方案
如果必须支持分散式初始化,可以通过自定义TypeScript转换器(Transformer)实现。转换器会在编译阶段遍历AST,收集所有setSmth调用的键和对应值的类型,生成一个全局的键值类型映射,然后替换getSmth的返回类型逻辑。
实现思路
- 编写TS转换器,遍历代码中的
obj.setSmth(key, value)调用节点,提取键的字面量值和值的类型信息。 - 收集所有键值对,生成一个
Record<Key, ValueType>类型。 - 修改
getSmth方法的类型定义,让其根据传入的键返回对应类型。
这种方案需要自定义TS编译流程,比如通过ts-loader(Webpack)或esbuild-plugin-tsc等工具集成转换器,或者直接使用ttypescript工具配合tsc的--transform参数(原生TS不支持直接指定转换器)。
其他变通方案
- 手动维护类型注册表:提前定义所有可能的键和类型的映射接口,然后让
setSmth和getSmth基于这个接口做类型约束。但这种方式失去了动态初始化的灵活性,需要提前预知所有键。 - 结合运行时类型库:比如用
zod定义运行时类型,同时生成对应的TypeScript类型,但同样需要提前定义结构,无法完全动态。
内容的提问来源于stack exchange,提问作者angry
相关产品推荐
相关产品推荐

