For this stage of the project setup, the focus is on TypeScript configuration: defining the main tsconfig, separating Node-specific settings, organizing shared type declarations, and adding a dedicated type-check command.
tsconfig.json
Update the file to the following:
{
"compilerOptions": {
"target": "ESNext", // 将代码编译为最新版本的 JS
"useDefineForClassFields": true,
"module": "ESNext", // 使用 ES Module 格式打包编译后的文件
"lib": ["ESNext", "DOM", "DOM.Iterable"], // 引入 ES 最新特性和 DOM 接口的类型定义
"skipLibCheck": true, // 跳过对 .d.ts 文件的类型检查
"esModuleInterop": true, // 允许使用 import 引入使用 export = 导出的内容
"sourceMap": true, // 用来指定编译时是否生成.map文件
"allowJs": false, // 是否允许使用js
"baseUrl": ".", // 查询的基础路径
"paths": {
// 路径映射,配合别名使用
"@/*": ["src/*"],
"@build/*": ["build/*"],
"#/*": ["types/*"]
},
/* Bundler mode */
"moduleResolution": "node", // 使用 Node/bundler 的模块解析策略
"allowImportingTsExtensions": true,
"resolveJsonModule": true, // 允许引入 JSON 文件
"isolatedModules": true, // 要求所有文件都是 ES Module 模块。
"noEmit": true, // 不输出文件,即编译后不会生成任何js文件
"jsx": "preserve", // 保留原始的 JSX 代码,不进行编译
/* Linting */
"strict": true, // 开启所有严格的类型检查
"noUnusedLocals": true, // 报告未使用的局部变量的错误
"noUnusedParameters": true, // 报告函数中未使用参数的错误
"noFallthroughCasesInSwitch": true // 确保switch语句中的任何非空情况都包含
},
"include": [
// 需要检测的文件
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"mock/*.ts",
"types/*.d.ts",
"vite.config.ts"
],
"exclude": [
// 不需要检测的文件
"dist",
"**/*.js",
"node_modules"
],
"references": [{ "path": "./tsconfig.node.json" }] // 为文件进行不同配置
}
This setup targets modern JavaScript with ESNext and keeps the module format aligned with Vite’s ES module workflow. It also brings in the latest language features alongside browser DOM typings through lib.
A few options here are especially practical in a Vue 3 project:
skipLibCheckavoids spending time type-checking declaration files.sourceMapkeeps source maps enabled during compilation.allowJs: falsemakes the project fully TypeScript-based.baseUrlandpathsdefine alias mappings such as@,@build, and#, which helps keep imports clean.resolveJsonModuleallows JSON imports directly.isolatedModulesensures every file can be treated as an ES module.noEmitprevents TypeScript from outputting compiled JavaScript files.jsx: preservekeeps JSX untouched.
On the type-safety side, strict checking is fully enabled with strict, while noUnusedLocals, noUnusedParameters, and noFallthroughCasesInSwitch help catch common mistakes early.
The include section covers .ts, .d.ts, .tsx, .vue, mock files, custom type declarations, and vite.config.ts. The exclude section removes dist, JavaScript files, and node_modules from checking.
The references field points to tsconfig.node.json, which makes it possible to separate configuration for different parts of the project.
tsconfig.node.json
Update this file as follows:
{
"compilerOptions": {
"composite": true, // 对于引用项目必须设置该属性
"skipLibCheck": true, // 跳过对 .d.ts 文件的类型检查
"module": "ESNext", // 使用 ES Module 格式打包编译后的文件
"moduleResolution": "Node", // 使用 Node/bundler 的模块解析策略
"allowSyntheticDefaultImports": true // 允许使用 import 导入使用 export = 导出的默认内容
},
"include": ["vite.config.ts"]
}
This file is used for Node-related TypeScript settings, especially for files like vite.config.ts. The composite option is required for referenced projects, which is why it appears here together with the references setting from the main config.
Organizing custom type declarations
Create a types directory to hold shared type definitions. For example, add an index.d.ts file like this:
type TargetContext = '_self' | '_blank'
type EmitType = (event: string, ...args: any[]) => void
type AnyFunction<T> = (...args: any[]) => T
type PropType<T> = VuePropType<T>
type Writable<T> = {
-readonly [P in keyof T]: T[P]
}
type Nullable<T> = T | null
type NonNullable<T> = T extends null | undefined ? never : T
interface Fn<T = any, R = T> {
(...arg: T[]): R
}
interface PromiseFn<T = any, R = T> {
(...arg: T[]): Promise<R>
}
This provides a simple place for utility types that can be reused across the project. As the project grows, more declaration files can be added as needed—for example:
global.d.tsfor global definitionsrouter.d.tsfor route-related typings
Add a type-check command
In package.json, add the following script:
"scripts": {
"type-check": "vue-tsc --noEmit"
},
After saving, run npm run type-check to check whether the project contains any type errors.