TypeScript
具有类型语法的JavaScript,一门强类型的编程语言
(Type)+javascript
let count:number = 100;
count = 100;
//为number类型只能用number类型赋值
适合用来开发中大型的项目,或者通用的JS代码库,再或者是团队协作开发的场景
搭建TS编译环境
无法直接在js引擎(浏览器/NodeJs)中运行
最终还需要经过编译转换成js代码才能运行
TS代码->TSC(TS编译引擎)->JS代码
既可以在开发时使用TS编写代码使用类型
也能保证实际运行时是JS代码
TS基础语法
类型注解
给变量添加类型约束,使变量只能被赋值为约定好的类型,同时可以有相关的类型提示
:string
约束变量message被赋值为string类型,具有string类型的提示
(字符串操作方法等)
常用类型注解
1,简单类型
number,string,boolean,null,undefined
简单类型
完全按照js类型书写
let age: number = 18;
let name: string = 'jack';
....
2,复杂类型
数组 函数
数组类型
限制变量的类型和数组成员的类型(ts会自动推断类型注解)
编码时可以提示数组的属性和方法(以及成员的属性和方法)
let arr:number[] = [1,2,3]
//创建一个number类型数组类型变量
let arr2:Array<number> = [1,2,3]
//同上,使用泛型进行数组类型声明
3,TS新增类型
联合类型,类型别名,接口(interface),字面量类型,泛型,枚举,void,any等
联合类型:
将多个类型合并为一个类型对变量进行注解
let arr3: (string | number)[] = [18,'jack']
表示arr3中的成员既可以是string类型也可以是number类型
类型别名:
通过type关键词给比较复杂的类型起一个别名,方便复用
类型别名使用大驼峰规范
type TestType = (string | number)[]
let arr: TestType = ['jack',100]
函数类型
给函数添加类型注解,本质上给函数的参数和返回值添加类型约束
function add(a:number,b:number):number{
return a+b;
}
注解类型的参数限制参数为必填
返回值注解类型限制函数的返回值必须满足要求
作用
避免参数不对导致的函数内部逻辑错误
对函数进行说明
箭头函数声明
普通声明
const Fun = (a:number,b:number):number => {
return a+b;
};
整体注解(针对函数表达式)
type FunType = (a:number,b:number) => number;
可选参数
代表参数可传可不传,一旦传递必须类型正确
//可选参数
function fun1(a:number,b?:number):string{
if(b){
return `${a}${b}`
}else{
return `${a}`
}
}
console.log(fun1(1));
console.log(fun1(1,2));
无返回值(void)
区别于undefined,void类型代表函数无返回值
//void
function fun2(a:number,b?:number):void{
}
interface接口
接口类型的作用
在TS中使用interface接口来描述对象数据的类型(常用于给对象的属性和方法添加类型约束)
interface P{
name:string
id: number
}
const person: P ={
...
...
}
对象的属性和方法必须都满足要求,不能多也不能少
在前后端数据通信时常用
eg:
收集表单对象数据的类型校验
渲染后端对象数组列表的智能提示
接口的可选设置
通过?对属性进行可选标注,在对象中可以选择设置或者不设置
在赋值时如果有值必须保证类型满足去求
接口的继承
接口之间可以通过extends实现继承,进行接口属性的复用,在子接口中自动继承了父接口的属性
interface P{
id:number
name:string
}
interface son extends P{
sonId:number
}
const person:son = {
id:111,
name:"",
sonId:222
}
type注解对象类型
和interface接口作用相似,对对象进行类型注解
注解对象
type Person = {
id:number
name:string
}
const p:Person = {
id:111,
name:""
}
type+交叉类型模拟继承
交叉类型:&,将一个类型注解设置为另外多个类型注解的并集
//父
type father = {
id:number
name:string
}
//子
type son1 = father&{
sonid:number
}
interface和type的对比
都能描述对象类型和实现继承
但type除了描述对象还能描述其他类型
同名的interface会合并取并集
同名的type会报错
推荐使用type更加灵活
字面量类型
直接将一个字面量值作为类型来描述一个变量
let count: 0
//count只能为0,不能将0以外的值赋值给count
作用
在需要一个精确的取值范围时
可以通过将字面量类型和联合类型结合来实现
type love = '男女' | '女男' | '男男' |'女女'
限制变量取值范围
字面量类型和const
const定义的变量会被推断为字面量类型
类型推论和any类型
类型推论
TS中存在类型推断机制,在没有给变量添加类型注解的情况下,TS也会给变量提供类型
eg:
在声明变量并赋值时
决定返回值类型时
…
any类型
变量被注解为any类型后,TS会忽略类型检查,检查的类型赋值不会报错也不会有任何的提示
let obj:any = {
age:18
}
obj.test = null
使用any会出现程序漏洞,要尽量避免使用
类型断言
如果认为TS推断不准确,可以使用断言将类型变得更加精确和具体
type Typetest = (string|number)
const test:Typetest;
console.log(test as number)
比如上述代码中,test变量可以是string或number,我们使用as断言其为number,如果传入的是一个string就会报错
泛型
Generics,是在定义接口,函数等类型时,不预先指定具体类型,在使用时再指定类型的一种特性.
使用泛型可以复用类型且让类型更加灵活
泛型接口
在接口类型的名称后使用声明一个泛型参数,在接口内使用这个参数类型
//定义泛型
type ResData<T> = {
msg: string
code: number
data: T
}
//使用泛型接口
let test:ResData<User> = {
...
}
泛型函数
在函数名称的后面声明一个泛型参数,在函数中对泛型进行使用
fuction Test<T>(a:number,b:T){
}
泛型约束
同java类型通配符,但是使用效果不同,所有拥有全部?内属性的类型全部都满足要求.
<T extends ?>
综合案例
仅挑重点写
进行类型声明
type CategoryItem = {//分类类型
id:string,
name:string,
picture:string,
children:CategoryItem,
parentId?:string,
parentName?:string,
goods?:good
}
type good = {//商品类型
id:string,
name:string,
desc:string,
price:string,
picture:string,
orderNum:number
}
type ApiResponseData<T> = {//响应类型
code:string,
msg:string,
result:T
}
/** 导航分类响应结果 */
export type NavCategoryResponseData = ApiResponseData<CategoryItem>;
/** 导航分类信息 */
export type NavCategoryData = CategoryItem;
创建axios请求
import * as nav from '@/types/nav';
import axios from 'axios';
export const getRequest = ()=>{
return axios.request<nav.NavCategoryResponseData>({
url:'/api/java-web/vue-rabbit/-/raw/master/src/data/category.json',
method:'get'
})
}
调用ts请求
const categorylist = ref<NavCategoryData>();
const getCategorylist = async() =>{
const result = await getRequest();
console.log(result);
categorylist.value = result.data.result;
}
onMounted(()=>{
getCategorylist();
})
使用v-for进行组件遍历
<li v-for="item in categorylist" :key="item.id">
<RouterLink to="`/category/${item.id}`">{{ item.name }}</RouterLink>
</li>