为什么捐赠
API 浏览器
联系站长
Quasar CLI with Webpack - @quasar/app-webpack
支持 TypeScript

如果在创建项目时未选择 TypeScript 支持,之后仍然可以添加。本指南将介绍如何为现有的基于 JavaScript 的 Quasar 项目添加 TypeScript 支持。

TIP

如果在创建项目时已选择了 TypeScript 支持,可以跳过本指南。

安装 TypeScript 支持

安装 typescript 包:


$ yarn add --dev typescript@~5.5.3

然后在项目根目录创建 /tsconfig.json 文件,内容如下:

/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,请手动创建:

/src/env.d.ts

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 属性。

/src/stores/index.ts

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 模式,请对项目进行以下修改,如果文件不存在则创建它们:

/src-pwa/pwa-env.d.ts

declare namespace NodeJS {
  interface ProcessEnv {
    SERVICE_WORKER_FILE: string;
    PWA_FALLBACK_HTML: string;
    PWA_SERVICE_WORKER_REGEX: string;
  }
}
/src-pwa/custom-service-worker.ts

// 在文件顶部
declare const self: ServiceWorkerGlobalScope & typeof globalThis & { skipWaiting: () => void };
/src-pwa/tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "lib": ["WebWorker", "ESNext"]
  },
  "include": ["*.ts", "*.d.ts"]
}

Electron 模式

如果您使用了 Electron 模式,请在项目中添加以下内容。

/src-electron/electron-env.d.ts

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 是一个元组,第一个元素是输入类型,第二个是输出类型。

/src-bex/background.ts

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 文件中也需要添加:

/src-bex/my-content-script.ts

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 支持。其内容应如下所示:

/tsconfig.json

{
  "extends": "./.quasar/tsconfig.json"
}

以下是生成的 tsconfig(非严格模式)的示例,供您参考,您的 /tsconfig.json 正是继承自它:

/.quasar/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 devquasar build 命令时自动生成。作为轻量级替代方案,可以使用 CLI 命令 quasar prepare 来生成 .quasar/tsconfig.json 文件和一些类型文件。这在 CI/CD 流水线中特别有用。

$ quasar prepare

您可以将其添加为 postinstall 脚本,确保在安装依赖后自动运行。这对于第一次拉取项目的人非常有帮助。

/package.json

{
  "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。示例如下:

/eslint.config.js

rules: {
  // ...
  '@typescript-eslint/consistent-type-imports': [
    'error',
    { prefer: 'type-imports' },
  ],
  // ...
}

quasar.config.ts

您可以通过 quasar.config 文件 > build > typescript 来控制 TypeScript 相关的行为。在配置中添加以下内容:

/quasar.config.ts

build: {
+  typescript: {
+    strict: true, // (推荐)启用 TypeScript 严格设置
+    vueShim: true, // 在使用 ESLint 的类型检查规则时需要,会为 `*.vue` 文件生成一个 shim 文件
+    extendTsConfig (tsConfig) {
+      // 您可以使用此钩子动态扩展 tsConfig
+      // 对于基本的使用场景,仍然可以通过修改 tsconfig.json 文件来覆盖部分设置
+    },
+  }
}

如果需要,您应该可以将 strict 选项设为 true 而不会遇到太多问题。但如果确实遇到了问题,可以在 tsconfig.json 中将"有问题的"选项暂时设为 false,等到能够修复时再启用。

如果您在使用 ESLint 的类型检查规则,请启用 vueShim 选项以保持之前 shim 文件的行为。如果项目在不启用该选项的情况下也能正常运行,则无需启用。

/quasar.config.ts

build: {
  typescript: {
+    vueShim: true // 在使用 ESLint 的类型检查规则时需要,会为 `*.vue` 文件生成一个 shim 文件
  }
}