Appearance
Vue3 + TypeScript 环境中的类型声明
问题背景
在 Vue + TypeScript + Vite 项目中,我们经常会在代码里导入非 TypeScript 文件,例如:
ts
import './tailwind.css'
import './layout.scss'
import MyComponent from './MyComponent.vue'TypeScript 默认只认识 .ts、.js、.tsx 等文件,遇到 .css、.scss、.vue 等后缀时会报错:
Cannot find module or type declarations for side-effect import of './tailwind.css'.这就需要类型声明文件来告诉 TypeScript:这些模块是存在的,它们长什么样。
类型声明文件
手动声明
手动为每种文件类型编写模块声明 env.d.ts:
ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<object, object, unknown>
export default component
}
declare module '*.css' {
const content: string
export default content
}
declare module '*.scss' {
const content: string
export default content
}declare module '*.vue' 是一个通配符模块声明,匹配所有以 .vue 结尾的 import 路径。声明的内容表示:所有 .vue 文件默认导出一个 DefineComponent。
什么是 .d.ts 文件
.d.ts 是 TypeScript 的类型声明文件。它不产生任何运行时代码,纯粹用于告诉 TypeScript 编译器某些模块、变量或类型的定义。
declare 关键字的意思是 “我声明这个事物存在,不需要实现它”。
三斜线指令引用 Vite 内置类型
ts
// env.d.ts
/// <reference types="vite/client" />vite/client 是 Vite 自带的类型声明文件,它内部已经声明了 .vue、.css、.scss、.png、.svg、.json 等各种静态资源模块。用 /// <reference types="..." /> 一次性把它们全部引入。
这也是 create-vue 脚手架生成的项目的默认写法。
生效原理
tsconfig.json 中配置了 "include": ["env.d.ts"],TypeScript 会自动扫描到同目录下的 env.d.ts 并加载其中的声明。之后整个项目中对应的 import 都不会报类型错误。
可以把它理解为给 TypeScript 装了一副 “眼镜”,让它能看懂 .css、.vue 等文件的 import。实际上这些文件最终由 Vite 处理(CSS 注入到 <style> 标签,.vue 编译为 JS 组件),TypeScript 只是需要一个声明来消除编译时的报错。