css-module-types可为每个.module.css生成精确.d.ts文件,导出带引号的类名如export const 'btn-primary': string,实现IDE跳转、提示及拼写报错,需确保路径匹配且tsconfig.include覆盖。

用 css-module-types 生成精确的 .d.ts 文件
手动写 declare module '*.module.css' 只能给 styles 加上 { [key: string]: string },IDE 不知道 styles.button 是否真实存在。要让类名可跳转、可提示、拼错就报错,必须把 CSS 文件里实际定义的类名“翻译”成类型声明——css-module-types 就是干这个的。
它不依赖插件或运行时,纯静态分析,生成的 .d.ts 和源文件一一对应,TypeScript 直接读取,零配置生效。
- 运行
npx css-module-types src/**/*.module.css,会为每个匹配文件生成同名.d.ts(如Button.module.css→Button.module.css.d.ts) - 生成文件必须和原 CSS 文件在**同一目录**,否则 TS 找不到;
tsconfig.json的include也要覆盖该路径(例如"include": ["src/**/*", "types/**/*"]) - 支持
.module.scss、.module.less等,但需确保文件名含.module.,且正则能匹配到(默认已支持) - 首次生成后建议加
--watch:npx css-module-types src/**/*.module.css --watch,CSS 类名增删会自动更新类型文件
typescript-plugin-css-modules 动态补全 vs 静态 .d.ts 的区别
这个插件不是生成文件,而是让 TypeScript 语言服务在内存中“实时推导”类名,对 .tsx 文件生效,但不产出物理 .d.ts。它快、轻量,但有硬性前提:
- VSCode 必须使用工作区的 TypeScript(
"typescript.tsdk": "node_modules/typescript/lib"),否则插件加载失败 - 只对
.ts/.tsx生效,.js文件里import styles from './x.module.css'依然无提示 - 如果项目用了 Vite,
vite-plugin-dts默认不打包这些动态类型,导出库时会丢类型 - CI 构建或非 VSCode 编辑器(如 Vim + tsserver)无法享受补全,而静态
.d.ts文件天然跨环境
为什么 typed-css-modules(tcm)现在不太推荐
tcm 曾经是主流方案,但它在 2025 年后逐渐暴露问题:
立即学习“前端免费学习笔记(深入)”;
- 不支持嵌套选择器提取(比如
.container .item不会生成item类型) - 对
@value、composes、:global等 CSS Modules 特性解析不稳定 - 输出格式固定为
export const xxx: string,无法处理带连字符的类名(如btn-primary)——除非手动加引号,但tcm不生成 -
css-module-types输出的是export const 'btn-primary': string,TS 支持,IDE 也认,更贴近真实 CSS 类名语义
生成的 .d.ts 文件要怎么写才不出错
别手写,但得知道生成结果长什么样,否则调试时容易误判。正确示例(来自 Button.module.css.d.ts):
export const 'primary': string; export const 'disabled': string; export const 'btn-large': string;
关键点:
- 类名含连字符、数字开头等非法标识符,必须用单引号包裹,不能写成
export const primary - 不要加
declare module或export default——这是模块声明文件(css-modules.d.ts)的事,这里是具体实现文件的类型映射 - 不要手动修改生成的
.d.ts,它会被覆盖;如有特殊需求(如重命名类名),应在 CSS 源文件里改,再重新生成 - 如果发现某个类名没出现在
.d.ts中,先检查它是否被:global包裹,或是否在媒体查询/嵌套规则里——css-module-types默认只提取顶层类名
include 漏了、文件名不匹配 .module.css,这三个地方错一个,就等于没生成。


















