必须声明 declare module '*.module.less' 类型,否则 typescript 将其视为字符串而非样式对象;需在 .d.ts 文件中正确定义并确保被 tsconfig.json 的 include 包含。

为什么 import styles from './index.module.less' 报错“类型‘string’上不存在属性”
因为 TypeScript 默认不认识 .module.less 文件,它把整个导入当成了一个字符串(即 import 返回 string),而不是你期望的 { container: string; header: string } 这样的对象。这不是 Webpack/Vite 的问题,是 TS 编译器压根没被告知“这种文件该长什么样”。
必须写 declare module '*.module.less',且位置和语法不能错
在项目中新建一个 types/css-modules.d.ts(路径名不重要,但后缀必须是 .d.ts),内容严格如下:
declare module '*.module.less' {
const classes: { [key: string]: string };
export default classes;
}
- 不能加
export =、const以外的修饰符(比如declare const或let classes都错) - 不能给
classes赋值(比如= { container: 'xxx' }是非法的) - 如果用
readonly [key: string]更严谨,但绝大多数项目用[key: string]就够用 - 这个文件必须被
tsconfig.json的include覆盖到,例如:"include": ["src/**/*", "types/**/*"]
只声明还不够:.less 文件得真是 CSS Modules 模式
类型声明只是“告诉 TS 怎么看”,但实际运行时样式是否局部化,取决于构建工具配置。比如 Vite 中需确保 .module.less 文件名带 .module. 前缀,且未被插件误判为普通 less。
- Vite 默认支持
*.module.less→ 自动启用 CSS Modules - Webpack 需在
css-loader中配modules: { mode: 'local' }并匹配/\.module\./ - 如果用了
index.less(没带.module.),即使写了declare module '*.less',TS 也不会触发模块导出逻辑 —— 它只会返回字符串 - 拼写错误如
className={styles.contianer}不会报 TS 错,因为[key: string]允许任意字符串访问;运行时才漏样式
想让 styles.container 真有类型提示?得生成具体 .d.ts
上面的全局 declare module 只能让代码过编译,但 IDE 不知道 container 是真实存在的类名。要获得自动补全和拼写校验,必须把每个 .module.less 文件里的类名“翻译”成类型定义。
- 可用工具如
typed-scss-modules(支持 less 需改源码或换less-to-js类工具) - 或手动生成:对
button.module.less写button.module.less.d.ts,内容为export const primary: string; export const large: string; - 这类方案维护成本高,适合核心组件库;业务项目通常接受“过编译 + 运行时检查”组合
tsconfig.json 包含、less 文件名没带 .module.、或者误以为声明后就能捕获所有拼写错误——其实它只保接口形状,不保类名真实性。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











