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中维护类型,可以将枚举类型与运行时值分离:
- 在
.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[] }
- 创建一个普通
.ts文件导出运行时对象:
// constants/addressRestrictions.ts export const AddressRestrictionType = { None: "None" as const, Blacklist: "Blacklist" as const, Whitelist: "Whitelist" as const, }
- 在
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
相关产品推荐
相关产品推荐

