必须为 css modules 添加类型声明,否则 typescript 编译报错 ts2307;在 types/css-modules.d.ts 中声明 declare module '*.module.css' { const classes: { [key: string]: string }; export default classes; },并确保 tsconfig.json 的 include 包含该文件。

直接写 import styles from './Button.module.css' 报错,不是 Webpack 或 Vite 配置没生效,而是 TypeScript 根本不知道这个文件导出什么——必须补上类型声明,否则连编译都过不去。
为什么 import 会报 TS2307 错误
TS 默认只认 .ts/.js 模块,遇到 .module.css 这类非 JS 文件,既不解析内容,也不推断结构。报错信息如 Cannot find module './Button.module.css' 或 Module has no exported member 'button',本质是类型系统“失明”了。
- 不是 loader 没处理 CSS,而是 TS 在编译阶段就卡住,IDE 也无法提示类名
- 即使你用的是 Vite 或 Webpack,只要没配类型声明,TS 就不会放行
import -
declare module '*.css'这种宽泛声明会破坏副作用导入(比如import 'normalize.css'),必须限定为*.module.css
最稳妥的声明方式:全局 .d.ts 文件
在项目里建一个 types/css-modules.d.ts(路径可自选,但需被 tsconfig.json 覆盖),内容严格按以下写:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { [key: string]: string };
export default classes;
}
- 不要加
export =、const以外的修饰符,也不要给classes赋值 - 用
readonly [key: string]更严谨,但多数项目用[key: string]就够 - 如果还用
.sass或.less模块,照着格式补对应declare module -
tsconfig.json的include必须包含该文件,例如:"include": ["src/**/*", "types/**/*"]
想获得类名自动提示?得生成具体 .d.ts
上面的全局声明能过编译,但 styles.xxx 是任意字符串——要让 styles.container 有类型校验和 IDE 提示,得靠工具把 CSS 里的类名“翻译”成类型定义。
- 推荐
css-module-types:运行npx css-module-types src/**/*.module.css,生成同名.d.ts文件 - 生成的
Button.module.css.d.ts必须和源文件在同一目录,否则 TS 找不到 - Vite 用户注意:
vite-plugin-dts默认不处理 CSS Modules,得额外配vite-plugin-css-modules-typings - Webpack 用户需确保
typings-for-css-modules-loader在css-loader之前执行
容易踩的坑:声明位置和模块匹配
声明文件写了,TS 还报错?大概率是路径或匹配规则不对。
-
declare module '*.module.css'不会匹配index.css,但会匹配index.module.css和components/Button.module.css - 声明文件若放在
src/types,而tsconfig.json的include只写了["src/**/*"],那它根本不会被加载 - VS Code 有时缓存旧声明,改完
.d.ts后要重启 TS Server(Ctrl+Shift+P → “TypeScript: Restart TS server”) - 如果用了
isolatedModules: true,声明文件里不能有import/export之外的语句,上面的declare module写法完全合规
真正麻烦的不是写几行声明,而是让声明路径、构建配置、IDE 缓存三者对齐——漏掉任意一环,styles.button 就还是 any。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










