Vue3+vite+Ts+pinia—第六章 TypeScript

6.1 TypeScript概述

TypeScript是由微软开发自由和开源的编程语言,它是JavaScript的一个超集。由于JavaScript属于弱类型语言,在编码过程中的常见拼写、类型等错误都不能预先检查。TypeScript的最初目标是成为JavaScript程序的静态类型检查器,但随着其发展,TypeScript的目标更多是开发大型应用,同时其代码可以编译生成纯JavaScript代码,并可运行在任何浏览器上。

TypeScript包含了JavaScript的全部特性,支持ES6标准,下图展示了TypeScript、JavaScript、ES5、ES6之间的关系。

由于TypeScript知识点非常庞大,在这里不能全部展开一一细说,只能了解一下我们在实战项目上比较常用的知识点。这里主要介绍一下ts的接口、泛型以及自定义类型,以及在Vue3上使用ts的流程。

6.2 ts中的接口

6.2.1 定义接口

假设定义一个Person对象,里面包含id、name、age这三个属性,它们分别是字符串、字符串和数字类型。对于这种确定对象属性以及属性的类型,我们可以使用接口对它进行约束。

在ts中,使用interface关键字来定义接口:

typescript 复制代码
// 定义一个接口,用于限制person对象的具体属性
interface PersonInter {
  id:string,
  name:string,
  age:number
}

注意:定义属性的类型,用的是小写,不要用大写。例如字符串使用string,不要写成String。

6.2.2 使用接口

定义好接口之后,别忘记要把它暴露出去,不然外部就无法引入。这里使用最直接的export把接口暴露出去。

typescript 复制代码
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInter {
  id:string,
  name:string,
  age:number
}

接下来就是引入ts文件了。

xml 复制代码
<script lang="ts" setup>
  import {PersonInter} from '@/types'
</script>

我们发现引入了之后代码飘红了,说明这里有问题。首先排除不是路径出问题,因为如果是路径错误,那么飘红的地方应该在from后面的路径那里。那么我们尝试使用一下这个接口:

使用了它还是飘红,因为以最新的规范而言,它是一个ts接口,不是一个具体的值。我们知道import引入一个具体的值,它是可以直接使用的,但是引入ts接口不行,它是一个规范,是一个类型,不能当作值来使用的。

由于引入的东西有可能是一个值,也有可能是一个类型,为了避免混淆,对于类型的引入,前面需要添加一个type关键字

此时ts接口约束已经生效,如果Person对象里没有包含id、name、age这三个属性,或者单词拼错,它就会提出警告提示:

6.3 ts中的泛型

说完对象再来看数组类型,假设有一个数组persons,它的每一项都是一个Person对象。既然它是一个数组,我们第一反应就是给它设置为Array类型:

bash 复制代码
<script lang="ts" setup>
  let personList:Array = [
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ]
</script>

但这样明显是不对的,因为数组是可以放任何东西的,也就是说单纯的指定数组类型是不够的,你还需要指定数组里的每一项是什么类型。

这个时候就涉及到泛型,泛型是一种特殊的数据类型,它可以在编码时不指定具体类型,而在使用时再确定类型。在数组中使用泛型就可以让数组中的元素保持统一的数据类型,在编译时也可以发现类型不匹配的错误。

在这里既然之前已经定义好Person对象的接口PersonInter,那么在数组的泛型直接使用它即可:Array<PersonInter>

xml 复制代码
<script lang="ts" setup>
  import {type PersonInter} from '@/types'
  
  let personList:Array<PersonInter> = [
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ]
</script>

这代码的含义是:定义一个personList变量,它是一个数组类型并且每一项都需要符合PersonInter接口规范。

6.4 ts中的自定义类型

有时候一个数组里可以包含多个类型,例如它可以写成Array<PersonInter, aaa, bbb, ccc, ...>,类似这种情况看起来就会显得比较臃肿,要是有多个地方出现这种情况,写起来感觉特别难受。

我们还有一种办法就是自定义类型,它用type关键字开头定义一个类型,然后可以根据需求来进行组合。像上述6.3的例子中,personList既要符合数组类型也要求每一项符合PersonInter接口,此时可以运用自定义类型:

typescript 复制代码
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInter {
  id:string,
  name:string,
  age:number
}

/* 一个自定义类型 */

// 第一种写法
// export type Persons = Array<PersonInter>

// 第二种写法
export type Persons = PersonInter[]

自定义类型之后,在使用的时候就显得比较简洁了:

bash 复制代码
<script lang="ts" setup>
  import {type Persons} from '@/types'
  
  let personList:Persons = [
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ]
</script>

6.5 对响应式数据使用ts

Vue3的响应式数据无非就是ref和reactive,对它们使用ts,有两种方式:

1、正常使用

其实不用管数据是否响应式,老老实实在变量名后面使用ts添加类型一样是可以的。

php 复制代码
<script lang="ts" setup>
  import {reactive} from 'vue'
  import {type Persons} from '@/types'
  
  let personList:Persons = reactive([
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ])
</script>

2、ref或reactive通过泛型使用

ref和reactive毕竟是官方推荐的,它也考虑到ts的结合,因此它还可以通过泛型的方式定义类型:

python 复制代码
<script lang="ts" setup>
  import {reactive} from 'vue'
  import {type Persons} from '@/types'
  
  let personList = reactive<Persons>([
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ])
</script>

6.6 示例代码

源码地址:gitee.com/huang_jing_...

文件目录:src_06_typescript

相关推荐
兰贝达24 分钟前
商品SKU选择器实现思路,包简单
前端·javascript·vue.js
懋学的前端攻城狮1 小时前
Vue源码解析-01:从创建到挂载的完整流程
前端·vue.js·源码
teeeeeeemo3 小时前
Vue数据响应式原理解析
前端·javascript·vue.js·笔记·前端框架·vue
Sahas10193 小时前
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
前端·javascript·vue.js
Jinxiansen02113 小时前
Vue 3 实战:【加强版】公司通知推送(WebSocket + token 校验 + 心跳机制)
前端·javascript·vue.js·websocket·typescript
我在北京coding4 小时前
Uncaught ReferenceError: process is not defined
前端·javascript·vue.js
baozj4 小时前
一次表单数据复用引发的 Bug:理解 Vue 中的 data 为何是函数
前端·javascript·vue.js
Nano4 小时前
ES6中的Proxy和Reflect:深入解析与Vue3响应式原理的完美结合
前端·vue.js
前端工作日常4 小时前
Vue源码中为何使用new Function而不使用eval?
vue.js
工业互联网专业4 小时前
基于django+vue的健身房管理系统-vue
vue.js·python·django·毕业设计·源码·课程设计·健身房管理系统