如何实现带键自动补全功能的TypeScript容器类
实现支持键自动补全的键值对容器类
要实现具备键自动补全功能的Container类,核心是利用TypeScript的泛型跟踪已添加的键,让类型系统能准确推断出所有可用键的联合类型。以下是具体实现:
class Container<Keys extends string = never, T = unknown> { private store: Record<Keys, T> = {} as Record<Keys, T>; set<K extends string>(key: K, value: T): Container<Keys | K, T> { const newStore = { ...this.store, [key]: value } as Record<Keys | K, T>; const newContainer = new Container<Keys | K, T>(); newContainer.store = newStore; return newContainer; } getAll(): Record<Keys, T> { return this.store; } } // 使用示例 const container = new Container<never, number>() .set('one', 1) .set('two', 2) .set('three', 3); container.getAll().one; // 自动补全"one"、"two"、"three" container.getAll().z; // TypeScript错误:类型上不存在属性"z"
实现说明
- 类的泛型参数
Keys用于跟踪已添加的键的联合类型,默认值为never(表示初始无键)。 set方法接收新键K,返回一个泛型更新为Keys | K的新Container实例,让TypeScript持续追踪所有已添加的键。getAll方法返回类型为Record<Keys, T>的对象,确保只有已添加的键能被访问,未定义键会触发类型错误。
从Map中提取键的联合类型
如果Map的初始键值对是已知的,可以通过TypeScript的条件类型和infer关键字提取键的联合类型:
// 初始化带有固定键值对的Map const myMap = new Map([ ['one', 1], ['two', 2], ['three', 3], ]); // 提取键的联合类型 type MapKeys = typeof myMap extends Map<infer K, unknown> ? K : never; // MapKeys 的类型为 "one" | "two" | "three"
注意事项
- 这种方式仅能提取Map初始化时的键类型,如果是运行时动态添加的键,TypeScript无法静态追踪,无法提取对应的类型。
内容的提问来源于stack exchange,提问作者Drenky
相关产品推荐
相关产品推荐

