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

如何定义TypeScript动态键字典 实现访问不存在Store时报错

核心解决方案

你需要给Registry类增加泛型参数,通过泛型自动推导传入的Store集合的精确类型,替代原来的字符串索引签名,即可实现不存在属性的报错提示。

问题原因

你之前的写法用了{ [name: string]: BaseStore }字符串索引签名,TypeScript会默认所有字符串key都符合类型定义,自然不会对不存在的属性做校验。

修改后的完整代码

registry.ts

// 你已有的BaseStore定义,构造函数接收Registry实例作为参数
export class BaseStore {
  constructor(public registry: Registry<any>) {}
}

// 泛型T约束为「键为字符串、值为接收Registry实例的Store构造函数」的对象
export default class Registry<T extends Record<string, new (registry: Registry<T>) => BaseStore>> {
  // stores的类型和传入的stores的key一一对应,值为对应Store的实例类型
  public stores: { [K in keyof T]: InstanceType<T[K]> };

  constructor(stores: T) {
    // 类型断言初始化空对象
    this.stores = {} as { [K in keyof T]: InstanceType<T[K]> };
    
    Object.keys(stores).forEach((name) => {
      const key = name as keyof T;
      const StoreCls = stores[key];
      this.stores[key] = new StoreCls(this);
    });
  }
}

实例化Registry示例

import * as stores from './stores.ts';
import Registry from './registry.ts';

// 泛型会自动推断传入的stores的类型,不需要手动传入
const registry = new Registry(stores);

// 正常访问,类型为UserStore实例,保留所有自定义属性方法提示
console.log(registry.stores.UserStore);
// 正常访问,类型为ListStore实例
console.log(registry.stores.ListStore);
// 访问不存在的属性,TypeScript会直接抛出错误提示
console.log(registry.stores.OtherStore);

补充说明

  • 如果你希望stores的key为小驼峰格式,比如userStore而非UserStore,只需要修改stores.ts的导出命名即可,泛型会自动同步推导key的变化。
  • 每个store的类型会保留其类定义的专属属性、方法,不会被统一降级为BaseStore类型,不影响正常的类型提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:45:03