如果在创建项目时未选择 TypeScript 支持,之后仍然可以添加。本指南将介绍如何为现有的基于 JavaScript 的 Quasar 项目添加 TypeScript 支持。
TIP
如果在创建项目时已选择了 TypeScript 支持,可以跳过本指南。
安装 TypeScript 支持
安装 typescript 包:
$ yarn add --dev typescript@~5.5.3然后在项目根目录创建 /tsconfig.json 文件,内容如下:
{
"extends": "./.quasar/tsconfig.json"
}在项目根目录运行 $ quasar prepare。
现在您就可以在项目中使用 TypeScript 了。请注意,部分 IDE 可能需要重启才能完全识别新配置。
TIP
请记住,您必须将 JavaScript 文件的扩展名改为 .ts 才能在其中编写 TypeScript 代码。要在 Vue 文件中使用 TypeScript,需要更新 script 标签添加 lang="ts" 属性,如 <script lang="ts"> 或 <script setup lang="ts">。
WARNING
如果忘记添加 tsconfig.json 文件,应用将在编译时报错!
代码检查配置
您可能需要查看相关的配置要求,详见这里。
TypeScript 声明文件
如果在创建项目时选择了 TypeScript 支持,以下声明文件会自动生成。如果当时未启用 TypeScript,请手动创建:
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: string;
VUE_ROUTER_MODE: "hash" | "history" | "abstract" | undefined;
VUE_ROUTER_BASE: string | undefined;
// 如果需要,在此定义您的自定义环境变量
}
}请根据您使用的功能和构建模式参考以下对应章节。
Pinia
如果您使用了 Pinia,Quasar CLI 会在 .quasar/pinia.d.ts 中自动扩展 router 属性。因此,不要在 src/stores/index.ts 文件的 PiniaCustomProperties 接口中手动添加 router 属性。
import { defineStore } from '#q-app/wrappers'
import { createPinia } from 'pinia'
- import { type Router } from 'vue-router';
/*
* 当向 store 添加新属性时,还应该
* 扩展 `PiniaCustomProperties` 接口。
* @see https://pinia.vuejs.org/core-concepts/plugins.html#Typing-new-store-properties
*/
declare module 'pinia' {
export interface PiniaCustomProperties {
- readonly router: Router;
+ // 如果有自定义属性,请在此添加
}
}PWA 模式
如果您使用了 PWA 模式,请对项目进行以下修改,如果文件不存在则创建它们:
declare namespace NodeJS {
interface ProcessEnv {
SERVICE_WORKER_FILE: string;
PWA_FALLBACK_HTML: string;
PWA_SERVICE_WORKER_REGEX: string;
}
}// 在文件顶部
declare const self: ServiceWorkerGlobalScope & typeof globalThis & { skipWaiting: () => void };{
"extends": "../tsconfig.json",
"compilerOptions": {
"lib": ["WebWorker", "ESNext"]
},
"include": ["*.ts", "*.d.ts"]
}Electron 模式
如果您使用了 Electron 模式,请在项目中添加以下内容。
declare namespace NodeJS {
interface ProcessEnv {
QUASAR_PUBLIC_FOLDER: string;
QUASAR_ELECTRON_PRELOAD_FOLDER: string;
QUASAR_ELECTRON_PRELOAD_EXTENSION: string;
APP_URL: string;
}
}BEX 模式
如果您使用了 BEX 模式,请在项目中添加以下内容。您可能需要根据实际使用的事件进行调整。key 是事件名称,value 是一个元组,第一个元素是输入类型,第二个是输出类型。
declare module "@quasar/app-webpack" {
interface BexEventMap {
/* eslint-disable @typescript-eslint/no-explicit-any */
log: [{ message: string; data?: any[] }, never];
getTime: [never, number];
"storage.get": [{ key: string | null }, any];
"storage.set": [{ key: string; value: any }, any];
"storage.remove": [{ key: string }, any];
/* eslint-enable @typescript-eslint/no-explicit-any */
}
}每个 content script 文件中也需要添加:
declare module "@quasar/app-webpack" {
interface BexEventMap {
/* eslint-disable @typescript-eslint/no-explicit-any */
"some.event": [{ someProp: string }, void];
/* eslint-enable @typescript-eslint/no-explicit-any */
}
}配置 TypeScript
tsconfig.json
注意项目根目录中的 /tsconfig.json 文件。Quasar CLI 通过该文件判断您是否需要 TypeScript 支持。其内容应如下所示:
{
"extends": "./.quasar/tsconfig.json"
}以下是生成的 tsconfig(非严格模式)的示例,供您参考,您的 /tsconfig.json 正是继承自它:
{
"compilerOptions": {
"esModuleInterop": true,
"skipLibCheck": true,
"target": "esnext",
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
"module": "preserve",
"noEmit": true,
"lib": [
"esnext",
"dom",
"dom.iterable"
],
"paths": { ... }
},
"exclude": [ ... ]
}要正确运行类型检查和代码检查,需要 .quasar/tsconfig.json 文件存在。该文件会在运行 quasar dev 或 quasar build 命令时自动生成。作为轻量级替代方案,可以使用 CLI 命令 quasar prepare 来生成 .quasar/tsconfig.json 文件和一些类型文件。这在 CI/CD 流水线中特别有用。
$ quasar prepare您可以将其添加为 postinstall 脚本,确保在安装依赖后自动运行。这对于第一次拉取项目的人非常有帮助。
{
"scripts": {
"postinstall": "quasar prepare"
}
}得益于这种配置,Capacitor 的依赖会被正确关联到项目的 TypeScript 配置中。这意味着您不必安装两次依赖——一次在 /src-capacitor 中,一次在根目录中。
这种变化的另一个好处是,文件夹别名(quasar.config 文件 > build > alias)会被 TypeScript 自动识别。因此您可以移除 tsconfig.json > compilerOptions > paths 的配置。如果您之前使用插件来处理这个问题,现在可以卸载它们,将 quasar.config 文件 > build > alias 作为唯一的配置来源。
如果您使用了 ESLint,我们建议在 ESLint 配置中启用 @typescript-eslint/consistent-type-imports 规则。如果您未配置代码检查,可以在 tsconfig.json 中使用 verbatimModuleSyntax 作为替代(与 ESLint 规则不同,它不支持自动修复)。这些变更有助于统一常规导入和纯类型导入的写法。更多信息请阅读 typescript-eslint 博客 - Consistent Type Imports and Exports: Why and How。示例如下:
rules: {
// ...
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'type-imports' },
],
// ...
}quasar.config.ts
您可以通过 quasar.config 文件 > build > typescript 来控制 TypeScript 相关的行为。在配置中添加以下内容:
build: {
+ typescript: {
+ strict: true, // (推荐)启用 TypeScript 严格设置
+ vueShim: true, // 在使用 ESLint 的类型检查规则时需要,会为 `*.vue` 文件生成一个 shim 文件
+ extendTsConfig (tsConfig) {
+ // 您可以使用此钩子动态扩展 tsConfig
+ // 对于基本的使用场景,仍然可以通过修改 tsconfig.json 文件来覆盖部分设置
+ },
+ }
}如果需要,您应该可以将 strict 选项设为 true 而不会遇到太多问题。但如果确实遇到了问题,可以在 tsconfig.json 中将"有问题的"选项暂时设为 false,等到能够修复时再启用。
如果您在使用 ESLint 的类型检查规则,请启用 vueShim 选项以保持之前 shim 文件的行为。如果项目在不启用该选项的情况下也能正常运行,则无需启用。
build: {
typescript: {
+ vueShim: true // 在使用 ESLint 的类型检查规则时需要,会为 `*.vue` 文件生成一个 shim 文件
}
}