Vite中的TS环境说明
vite天然引入ts。
Vite仅仅执行ts文件的转译工作,但是不会执行类型检查。因为已经默认你在IDEA/Vscode等编译器 或 构建过程里进行检查了,因此不会管了。
比如类型出错了,也依旧能够执行。
在main.ts改一下
let count: number = 100count = 200console.log(count)//200count = 'hello'console.log(count)//'hello'
依旧运行了。
那么,构建过程里怎么验证的呢?
我们在package.json里其实已经配置过了
"build": "vue-tsc --noEmit && vite build"
只有验证通过了,才会vite build
真的么?验证下,上面的错误我不修改,看看。
npm run buildsrc/main.ts:7:1 - error TS2322: Type 'string' is not assignable to type 'number'.7 count = 'hello'~~~~~Found 1 error in src/main.ts:7
果然报错了
在Vite里使用esbuild将TS转译成JS,比vue用的tsc快20-30倍,同时HMR更新反映到浏览器的时间小于50ms.
但是,因为esbuild只执行转译工作而不包含类型信息,所以不支持TS的特定功能例如常量枚举和隐式”type-only“导入。
所以我们必须在tsconfig.json中compilerOptions里设置"isolatedModules":true,这样TS才会警告我们哪些功能无法与esbuild这种独立编译模式一同工作。
(后来的版本已经默认设置了,无需进行这步了。)
客户端类型
Vite默认的类型定义是写给它的Node.js API的,不是给客户端代码环境的。如果要将其补充到一个Vite应用的客户端代码环境中,得添加一个d.ts声明文件:
/// <reference types="vite/client" />
同时,也可以将vite/client添加到tsconfig中的compilerOption.types下
{"compilerOptions": {"types": ["vite/client"]}}
这将会提供以下类型定义补充:
- 资源导入 (例如:导入一个
.svg文件) import.meta.env上 Vite 注入的环境变量的类型定义import.meta.hot上的 HMR API 类型定义
主要就提供这三个,若没引入则没有。不过默认引入的d.ts声明文件的,叫vite-env.d.ts
在以前除了vite-env.d.ts, 还有shims-vue.d.ts,而最新版本已经将他直接加到vite-env.d.ts里了,也是ts的补充声明。 以下:
declare module '*.vue' {import type { DefineComponent } from 'vue'const component: DefineComponent<{}, {}, any>export default component}
declare了一个 ‘.vue’, 以vue结尾的。在vue里加载了DefineComponent,定义了下又将其导出。其作用:*给Vue做类型声明,因为ts识别不了vue模块!
Vue3中的TS支持
其实vue3就是用ts编写的,对TS提供了一等公民的支持。所有的 Vue 官方库都自带了类型声明文件,开箱即用。
主要是项目配置。
项目配置
在单文件组件中的用法
要在单文件组件中使用 TypeScript,比如App.vue。需要在 <script> 标签上加上 lang="ts" 的 attribute。当 lang="ts" 存在时,所有的模板内表达式都将享受到更严格的类型检查。
简而言之,将lang="ts", 就将其下内容当做ts来使用了。最后编译构建时,转成js。不加lang="ts",就是js来对待。
<script lang="ts">import { defineComponent } from 'vue'
也可以用于 <script setup>:
<script setup lang="ts">// 启用了 TypeScriptimport { ref } from 'vue'const count = ref(1)</script>
定义Vue组件
为了让 TypeScript 正确地推导出组件选项内的类型,需要用defineComonent全局方法来定义组件
import { defineComponent } from 'vue'export default defineComponent({// 启用了类型推导props: {name: String,msg: { type: String, required: true }},data() {return {count: 1}},mounted() {this.name // 类型:string | undefinedthis.msg // 类型:stringthis.count // 类型:number}})
总结:
- lang=”ts”
- 要让TS正确推断Vue组件选项中的类型,需要使用
defineComponent全局方法定义组件。
与组合式API一起使用
当使用 <script setup> 时,defineProps() 宏函数支持从它的参数中推导类型:
简而言之,在setup里,可以判断props组件里的类型,是字符串还是数字,都知道。
<script setup lang="ts">const props = defineProps({foo: { type: String, required: true },bar: Number})props.foo // stringprops.bar // number | undefined</script>
PropType
若props的一个参数obj要定义一个有格式要求的对象怎么办?
并且没有使用
