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 示例代码
文件目录:src_06_typescript