如果你在创建项目时没有选择 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 文件,应用在编译时会报错!
Lint 配置
你可能需要查看相关的配置要求,详见这里。
TypeScript 声明文件
如果你在项目脚手架搭建时选择了 TypeScript 支持,以下声明文件会自动生成。如果创建项目时没有启用 TypeScript 支持,请手动创建:
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: string;
VUE_ROUTER_MODE: "hash" | "history" | "abstract" | undefined;
VUE_ROUTER_BASE: string | undefined;
// Define any custom env variables you have here, if you wish
}
}请根据你使用的功能和构建模式,参阅以下相应章节。
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';
/*
* When adding new properties to stores, you should also
* extend the `PiniaCustomProperties` interface.
* @see https://pinia.vuejs.org/core-concepts/plugins.html#Typing-new-store-properties
*/
declare module 'pinia' {
export interface PiniaCustomProperties {
- readonly router: Router;
+ // add your custom properties here, if any
}
}PWA 模式
如果你使用了 PWA 模式,请对项目做以下修改,如果文件不存在则创建它们:
declare namespace NodeJS {
interface ProcessEnv {
SERVICE_WORKER_FILE: string;
PWA_FALLBACK_HTML: string;
PWA_SERVICE_WORKER_REGEX: string;
}
}// at the top of the file
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-vite" {
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 */
}
}你还需要在每个内容脚本文件中添加:
declare module "@quasar/app-vite" {
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 file > build > alias)会被 TypeScript 自动识别。因此你可以移除 tsconfig.json > compilerOptions > paths 的配置。如果你在使用 vite-tsconfig-paths 之类的插件,可以卸载它,直接以 quasar.config file > 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 file > build > typescript 来控制 TypeScript 相关的行为。在配置中添加以下内容:
build: {
+ typescript: {
+ strict: true, // (recommended) enables strict settings for TypeScript
+ vueShim: true, // required when using ESLint with type-checked rules, will generate a shim file for `*.vue` files
+ extendTsConfig (tsConfig) {
+ // You can use this hook to extend tsConfig dynamically
+ // For basic use cases, you can still update the usual tsconfig.json file to override some settings
+ },
+ }
}如果需要,你应该可以直接将 strict 选项设置为 true 而不会遇到太多问题。但如果确实出现了问题,你可以在 tsconfig.json 文件中将"有问题"的选项设置为 false,至少先这样用着,直到你有时间去修复它们。
如果你在使用 ESLint 的类型检查规则,请启用 vueShim 选项以保持之前 shim 文件的行为。如果你的项目在没有该选项的情况下运行正常,则不需要启用它。
build: {
typescript: {
+ vueShim: true // required when using ESLint with type-checked rules, will generate a shim file for `*.vue` files
}
}