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

如何在Bun中用require引入类并避免TS2749错误?

解决TypeScript中require引入类/变量赋值类无法直接作为类型的问题

问题重现

模块引入场景

foo.ts文件:

export default class Foo { name = 'bar' }

使用require引入的代码:

const Foo = require('./foo').default
function logFoo(foo: Foo) { console.log(foo) }
logFoo(new Foo)

运行bun test.ts可正常执行,但TypeScript会抛出错误:TS2749: 'Foo' refers to a value, but is being used as a type here. Did you mean 'typeof Foo'?

单文件场景

class Foo { name = 'bar' }
const It = Foo
function logFoo(foo: It) { console.log(foo) }
logFoo(new Foo)

同样触发TS2749错误,但直接用Foo作为类型则正常。

需求约束

  1. 不能用import替换require;
  2. 不能用typeof声明参数类型,要求require引入的类、本地类、import引入的类的函数参数声明方式完全一致。

解决方案

1. 模块引入(require)场景

通过InstanceType结合typeof提取实例类型,同时保留require的赋值逻辑:

// 先定义与变量同名的类型别名,获取类的实例类型
type Foo = InstanceType<typeof require('./foo').default>
// 用require赋值变量
const Foo = require('./foo').default

function logFoo(foo: Foo) { console.log(foo) }
logFoo(new Foo)

这里的type Foo是类的实例类型,和import Foo from './foo'中直接用Foo作为类型的写法完全一致,满足参数声明方式统一的要求。

2. 单文件场景

直接为变量定义同名的类型别名,复用原类的实例类型:

class Foo { name = 'bar' }
// 定义类型别名It,指向Foo的实例类型
type It = Foo
// 变量It赋值为Foo构造函数
const It = Foo

function logFoo(foo: It) { console.log(foo) }
logFoo(new Foo)

此时参数foo: It的写法和直接用foo: Foo完全一致,不会触发TS2749错误。

原理说明

TypeScript中,class Foo同时代表两个东西:

  • 值:类的构造函数;
  • 类型:类的实例类型。
    但当你把构造函数赋值给变量(比如const It = Foo或const Foo = require(...))时,变量仅代表构造函数这个值,不自带实例类型。通过定义同名/同标识的类型别名,我们手动把实例类型绑定到变量名上,让它具备和原类名一样的“值+类型”双重身份,从而实现参数声明方式的统一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:55:20