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

NextJS中types.d.ts导出enum报错:无法解析@/types

解决Next.js中types.d.ts导出enum导致的「Module not found: Can't resolve '@/types'」错误

问题根源

TypeScript的enum是类型与运行时值的结合体,而interface仅作为类型存在,编译阶段会被完全擦除。当你在.d.ts文件中导出enum时,由于它包含需要在运行时存在的具体值,Next.js的打包流程会尝试解析这个模块,但.d.ts是类型声明文件,加上你tsconfig.json中开启了noEmit: true,不会生成对应的JS输出文件,最终导致运行时找不到模块。而interface因为没有运行时内容,所以不会触发这个问题。

可行解决方案

方案1:将enum迁移到.ts文件中

把包含enum的代码从.d.ts移到普通.ts文件,这样Next.js会编译该文件生成可被运行时加载的JS代码:

// types.ts
export enum AddressRestrictionType {
  None = "None",
  Blacklist = "Blacklist",
  Whitelist = "Whitelist",
}

export interface AddressRestrictions {
  uuid: string | null
  restrictionType: AddressRestrictionType
  targetIpv4: string
  targetIpv6: string
  targetTenants?: Tenant[]
  targetUsers?: IPDefenseUser[]
  targetUserGroups?: IPDefenseUserGroup[]
}

之后在page.tsx中正常导入即可:

import { AddressRestrictionType } from '@/types'

const schema = z.object({
  restrictionType: z.enum([AddressRestrictionType.Blacklist, AddressRestrictionType.Whitelist, AddressRestrictionType.None]),
  addressIpv4: z.string().ip("v4"),
  addressIpv6: z.string().ip("v6"),
})

方案2:改用const enum替代普通enum

const enum在编译阶段会被直接替换为对应的字面量值,不会生成运行时的枚举对象,因此不会触发模块解析问题:

// types.d.ts
export const enum AddressRestrictionType {
  None = "None",
  Blacklist = "Blacklist",
  Whitelist = "Whitelist",
}

export interface AddressRestrictions {
  uuid: string | null
  restrictionType: AddressRestrictionType
  targetIpv4: string
  targetIpv6: string
  targetTenants?: Tenant[]
  targetUsers?: IPDefenseUser[]
  targetUserGroups?: IPDefenseUserGroup[]
}

注意:确保tsconfig.json中preserveConstEnums为false(默认值),否则仍会生成运行时枚举对象,问题依旧。

方案3:用类型+对象模拟enum

如果你坚持要在.d.ts中维护类型,可以将枚举类型与运行时值分离:

  1. 在.d.ts中声明类型:
// types.d.ts
export type AddressRestrictionType = "None" | "Blacklist" | "Whitelist"

export interface AddressRestrictions {
  uuid: string | null
  restrictionType: AddressRestrictionType
  targetIpv4: string
  targetIpv6: string
  targetTenants?: Tenant[]
  targetUsers?: IPDefenseUser[]
  targetUserGroups?: IPDefenseUserGroup[]
}
  1. 创建一个普通.ts文件导出运行时对象:
// constants/addressRestrictions.ts
export const AddressRestrictionType = {
  None: "None" as const,
  Blacklist: "Blacklist" as const,
  Whitelist: "Whitelist" as const,
}
  1. 在page.tsx中分别导入类型和值:
import type { AddressRestrictionType } from '@/types'
import { AddressRestrictionType as AddressRestrictionTypeValues } from '@/constants/addressRestrictions'

const schema = z.object({
  restrictionType: z.enum([AddressRestrictionTypeValues.Blacklist, AddressRestrictionTypeValues.Whitelist, AddressRestrictionTypeValues.None]),
  addressIpv4: z.string().ip("v4"),
  addressIpv6: z.string().ip("v6"),
})

验证步骤

修改完成后,重启Next.js开发服务器(避免缓存导致的问题),再运行项目即可确认错误是否消失。

内容的提问来源于stack exchange,提问作者Papp Zoltán

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:24:59