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

Jest未执行TypeScript模块末尾静态方法的问题排查

问题:测试中Builder实例返回undefined的排查与解决

代码文件

Builders.ts

// Builders.ts
import {Registry} from "./Registry";

export interface IBuilder {
    build: () => void;
}

class NiceBuilder implements IBuilder {
    build(): void {
        console.log('Nice builder')
    }
}

class SuperBuilder implements IBuilder {
    build(): void {
        console.log('Super Builder')
    }
}

Registry.registerBuilder(new NiceBuilder());
Registry.registerBuilder(new SuperBuilder());

Registry.ts

// Registry.ts
import {IBuilder} from "./Builders";

export class Registry {
    static builders: Array<IBuilder> = [];
    static registerBuilder(builder: IBuilder) {
        this.builders.push(builder);
    }

    static getBuilder(): IBuilder {
        return this.builders[0];
    }
}

Builder.test.ts

// Builder.test.ts
import {Registry} from "../../../Registry";
import {IBuilder} from "../../../Builders";

describe('test builders', () => {
    it('test', () => {
        const builder: IBuilder = Registry.getBuilder();
        console.log(builder); // logs undefined why???????
    });
});

问题原因

  1. Builders.ts未被实际加载执行:测试文件仅导入了IBuilder接口,而TypeScript接口编译为JavaScript后会被完全移除,运行时不会触发Builders.ts的顶层代码执行——你期望的注册逻辑根本没运行。
  2. 循环依赖隐患:Registry.ts和Builders.ts互相导入,即便加载了Builders.ts,也可能因循环依赖导致注册逻辑执行时机异常,出现实例未被正确添加的情况。

解决思路

  • 强制加载Builders.ts:在测试文件中直接导入Builders.ts,无需使用它的任何导出内容,确保运行时执行注册逻辑:

    // Builder.test.ts
    import {Registry} from "../../../Registry";
    import {IBuilder} from "../../../Builders";
    import "../../../Builders"; // 新增此行,触发文件执行
    
    describe('test builders', () => {
        it('test', () => {
            const builder: IBuilder = Registry.getBuilder();
            console.log(builder); // 现在会输出NiceBuilder实例
        });
    });
    
  • 拆分接口解决循环依赖(推荐):把IBuilder接口抽成独立文件,避免Registry和Builders互相导入:

    1. 创建BuilderTypes.ts:
      // BuilderTypes.ts
      export interface IBuilder {
          build: () => void;
      }
      
    2. 修改Registry.ts:
      // Registry.ts
      import {IBuilder} from "./BuilderTypes";
      
      export class Registry {
          static builders: Array<IBuilder> = [];
          static registerBuilder(builder: IBuilder) {
              this.builders.push(builder);
          }
      
          static getBuilder(): IBuilder {
              return this.builders[0];
          }
      }
      
    3. 修改Builders.ts:
      // Builders.ts
      import {Registry} from "./Registry";
      import {IBuilder} from "./BuilderTypes";
      
      class NiceBuilder implements IBuilder {
          build(): void {
              console.log('Nice builder')
          }
      }
      
      class SuperBuilder implements IBuilder {
          build(): void {
              console.log('Super Builder')
          }
      }
      
      Registry.registerBuilder(new NiceBuilder());
      Registry.registerBuilder(new SuperBuilder());
      

这样既解决了测试中注册逻辑不执行的问题,也消除了循环依赖带来的潜在风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:20:26