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

TypeScript库中如何同时导出接口与具体类并实现接口调用

解决TypeScript接口导出为对象属性时的TS2693错误

问题原因

你遇到的TS2693错误本质是:TypeScript的接口是类型,仅存在于编译阶段,编译为JavaScript后会被完全擦除,无法像类(属于值)那样作为对象的属性导出。直接把接口放到导出对象里,TS会认为你在试图将一个不存在的“值”赋值给对象属性,因此报错。

解决方案

根据你希望使用者通过mylib.IFoo和mylib.Foo调用的需求,推荐以下两种可行方案:

方案1:导入整个模块作为命名空间(最简洁)

这种方式符合TypeScript模块化规范,无需额外声明:

  1. 在src/index.ts中直接导出接口和类:
export interface IFoo {
  doSomething(): void;
}

export class Foo implements IFoo {
  doSomething() {
    // 你的实现逻辑
    console.log('执行Foo的doSomething方法');
  }
}
  1. 在test/Foo.spec.ts中导入整个模块并使用:
import * as mylib from '../src';

const foo: mylib.IFoo = new mylib.Foo();
foo.doSomething(); // 正常调用

方案2:通过声明合并实现对象+类型的导出

如果你必须将类封装在mylib对象中导出,同时保留接口的类型访问,可以用声明合并的方式:

  1. 在src/index.ts中:
// 定义接口
export interface IFoo {
  doSomething(): void;
}

// 定义并实现类
export class Foo implements IFoo {
  doSomething() {
    console.log('执行Foo的doSomething方法');
  }
}

// 创建包含类的导出对象
export const mylib = {
  Foo
};

// 声明mylib的命名空间,让它包含IFoo类型
declare namespace mylib {
  export type IFoo = import('./index').IFoo;
}
  1. 在test/Foo.spec.ts中直接使用:
import { mylib } from '../src';

const foo: mylib.IFoo = new mylib.Foo();
foo.doSomething();

关键说明

  • 类型(接口、类型别名等)和值(类、函数、变量等)在TypeScript中属于不同的空间,不能直接混在一起作为对象属性导出。
  • 方案1是TypeScript官方推荐的模块化使用方式,代码更简洁易维护;方案2适合需要将类封装在特定对象下的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:12:44