vue3入门39 - Vite 基础 - typeScript使用问题

669 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情

前言

  • Vite 天然支持引入 .ts 文件。但是只做编译,不做校验,并且有一些问题也需要注意下。

编译时做 ts 校验

  • 修改 package.json 下 scripts
"scripts": {
  "dev": "vite",
  "build": "tsc --noEmit && vite build",
  "serve": "vite preview"
},
  • 安装 typescript
yarn add typescript -D
  • 添加 tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "suppressImplicitAnyIndexErrors": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules",
    "src/assets/json/*.json",
    "src/assets/css/*.scss"
  ]
}
  • 配置好之后,打包时会校验 ts

vue-tsc for SFC

  • 如果 .vue 文件使用 ts 需要单独安装 vue-tsc 做 ts 校验
  • 安装
yarn add vue-tsc
"scripts": {
  "dev": "vite",
  "build": "vue-tsc --noEmit && tsc --noEmit && vite build",
  "serve": "vite preview"
},

isolatedModules

  • 因为 vite 提供的 ts 编译,只针对语法,只是针对单文件的,而对于 typescript 是可以关联不同文件之间的信息的。vite 在编译时不会读取其他文件信息,导致有些 typescript 一些功能无法使用。所有 要配置这个选项isolatedModules,来告诉现在 ts 环境中是不支持模块间关联校验的。

  • 在 tsconfig.json 配置

 "compilerOptions": {
    "isolatedModules": true,
  }
  • Exports of Non-Value ldentifiers
  • Non-Module Files
  • References to const enum members

Exports of Non-Value ldentifiers

  • 在项目中创建两个代码文件
// types.ts
export interface A {
  name: string;
}

// test.ts
import { A } from "./types";
export const a: A = {
  name: "张三",
  // age: 18,
};

export { A };
  • 报错

    • Uncaught SyntaxError: The requested module '/src/types.ts' does not provide an export named 'A'
  • 对于 vite 来说,编译 test.ts 文件的时候,会发现 A 并没有存在,

  • 因为 A 只是一个 ts 类型,编译为 js 之后,由于 js 里没有 interface 这个概念,导致导出的时候找不到这个 A,无法导出。

  • 如果我们只是引入使用,js 编译之后 A 就去掉了是可以的。

  • 当我们开启 "isolatedModules": true 选项,就可以在写代码时获得报错信息,

image.png

  • build时 也会获得对应的报错信息

image.png

Non-Module Files

  • 新建一个文件,不做导入导出
// no-export.ts
const a = "111";
  • 报错
    • 'no-export.ts' cannot be compiled under '-- isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module. ts( 1208)
  • 我们必须通过 import export 让此文件让 ts 认为这是一个模块

image.png

References to const enum members

import { A } from "./types";

declare const enum Num {
  First = 0,
  Second = 1,
}

export const a: A = {
  name: "张三",
  age: Num.First,
};

export { A };
  • 报错:

    • Uncaught ReferenceError: Num is not defined
    • Cannot access ambient const enums when the isolatedModules' flag is provided. ts(2748)
  • 在 ts 环境中,enum 定义的数据,在使用过程中会直接替换为对应的常量,

  • 在 vite 环境中,不能识别 enum 这种语法,会直接把 declare const enum Num 定义直接去掉,引用的是 Num.First 找不到 Num 变量

  • 当我们开启 "isolatedModules": true 选项,就可以在写代码时获得报错信息,

image.png

  • build时 也会获得对应的报错信息

image.png

client types

  • ts 提供了一些内置对象,例如
import.meta
  • 我们就需要让 ts 认识这种语法,通过配置 tsconfig.json
{
  "compilerOptions": {
  	"types": ["vite/client"],
  }
}
  • 配置完之后可以获得代码提示,可以知道 vite 中有哪些可以使用的内置变量

image.png