TypeScript
1.TS是什么
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6+ 的支持
本质上来讲 ts是在js的基础上添加了可选的静态类型和基于类的面向对象编程
2.TS特性
TypeScript 主要有 3 大特点:
- 始于JavaScript,归于JavaScript
TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 3(或更高版本)的JavaScript 引擎中。
- 强大的类型系统
类型系统允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。可以友好的在编辑器中提示错误, 编译阶段就能检查出大部分错误
- 先进的 JavaScript
TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性,以帮助建立健壮的组件。
3.JavaScript与TypeScript区别
3.1类型绑定
JavaScript是动态绑定类型, 只有运行程序才能知道类型, 在程序运行之前JavaScript对类型一无所知
TypeScript是在程序运行之前就会知道当前变量是什么类型。如果该变量并未定义类型, TypeScript会自动类型推导出来(但是ts中函数是不会自动类型推导的) 。如下:
此时变量str
的类型被推断为字符串类型
3.2 类型转换
JavaScript中存在隐式转换, 此时会将Boolean
类型的true
转变成number
类型 再与前面的1相加成2
const a = 1 + true
console.log(a) // 输出结果为 2
TypeScript中, 如上的代码会直接报错, 提示number
类型不能与Boolean
类型进行运算
3.3 类型检查时间
JavaScript只有在程序运行中才能类型检查,类型也会存在隐式转换
TypeScript在编译时就会被类型检查, 如果与预期类型不符合就会在编辑器报错
Vue3
首先Vue本身就是用 TypeScript 编写的,并对 TypeScript 提供了支持。所有的 Vue 官方库都自带了类型声明文件,开箱即用
可以更好的逻辑复用与代码组织
在使用方面,Vue3从选项式Api转变为组合式Api,允许我们按功能组织数据和方法。打破了data(){}、methods:{}等固定结构的束缚,
1.随着功能的增长,复杂组件的代码变得越来越难以阅读和理解。这种情况在开发人员阅读他人编写的代码时尤为常见。根本原因是 Vue 现有的 API 迫使我们通过选项组织代码,但是有的时候通过逻辑关系组织代码更有意义
2.目前缺少一种简洁且低成本的机制来提取和重用多个组件之间的逻辑
更好的类型推导
使用
JavaScript语言本身的缺陷----弱类型, 比如 在JavaScript语言中, 一个变量, 可以先后保存不同类型的数据
var a = 'abc' //此时a是一个保存字符串数据的变量
a = 2 // 给a重新赋值, 此时a是一个保存整数数据的变量
在大型项目的协作开发中, 强调的是严格和标准化. vue3和ts语言的结合, 实现了强类型检查 在编写程序的时候, 需要严格定义好要传递的数据类型和数据结构. 在编码的过程中, 开发者都要严格遵守数据类型和数据结构的规定.
TypeScript可以让我们在开发中避免一些类型或者一些不是我们预期希望的代码结果错误
eg: xxx is not defined
这种错误是JavaScript在运行中才会跑出的错误, 而TypeScript在使用过程中, 脚手架有自带的类型检查, 开发者在编码时, 一旦有类型使用错误, 就会报错
1.在单文件组件中的用法
在单文件组件中使用TypeScript, 需要在<script>
标签上加上lang="ts"
的属性, 当lang="ts"
存在时, 所有的模板内表达式都要接收严格的类型检查
<script lang="ts">
</script>
2.定义ts类型
ref
简单类型(可以使用泛型定义)
const value = ref<string | number>(0)
//2
let a = ref("a" as string);
复杂类型(可以定义interface等, 再写进泛型里)
定义接口可以进行接口的复用
interface Person{
name: string;
age: number;
}
在使用该interface时, 能够很好的给出对应属性名以及数据类型
reactive(一般用来定义引用类型数据, 对象或者数组
我们以泛型去定义他们的类型 照样会有提示
defineProps
我们一般通过defineProps函数接收父组件传来的参数
<!-- 父组件代码 -->
<template>
<HelloWorld msg="Welcome to Vue.js + TypeScript App" :age="age" />
</template>
<script setup lang="ts">
import {ref} 'vue'
const age = ref<number>(12)
</script>
<!-- 子组件代码 -->
<template>
<h1>{{ props.msg }}</h1>
<h2>{{ props.age }}</h2>
</template>
<script setup lang="ts">
import {ref, defineProps} 'vue'
//定义接收父组件传来的数据接口
inteface Props {
msg: string;
age: number
}
const props = defineProps<Props>()
//设置默认值
const props = withDefaults(defineProps<Props>(), {
msg: "sfhjkd",
age: 12,
});
</script>
子组件对应页面截图
interface
在项目中使用的较多就是接口---interface
interface People {
name: string;
age: number
}
const personOne: People = {
name: 'one',
age: 11
}
const personTwo: People = {
name: 'two',
age: 12
}
//使用interface定义了一个People的接口, 赋值给了personOne和personTwo两个变量, 实现了接口的复用
readonly修饰符
interface People {
readonly name: string;
age: number
}
const personOne = ref<People>({
name: 'one',
age: 11
})
在修改name
属性时, 会提示以为name
属性是一个只读属性, 所以没法修改
?可选修饰符
interface People {
name: string;
age: number;
sex?: string
}
const personOne = ref<People>({
name: 'one',
age: 11
})
接口中 sex
属性是可选属性, 被赋值的personOne
中并未定义sex
的属性, 是不会报错的
extends继承
interface People {
name: string;
age: number;
sex?: string
}
interface Student extends People {
idCard: string;
className: string
}
由图可以看出, 接口Student
包含了自己本身定义的idCard
和className
属性, 还有继承People
的name
、age
和 sex
属性
propName扩展
当接口定义好之后, 我们想在变量上自定义属性可以使用propName
interface human {
name: string;
age: number;
[propName: string]: any // 表示propName字段是string类型, 对应的value值可以是任意类型
}
const someOne: human = {
name: 'lin',
age: 12,
address: 'dfhkafgkdf' //此时不会报错
}
Type类型
用来声明类型别名
别名类型只能定义基础静态类型、对象静态类型、元组、联合类型(不可以定义interface类型)
也可以使用readonly修饰符以及 ?可选修饰符
type Types = string | number //基本数据类型 联合类型
type UserObj = {
name:string,
age:string
} // 对象
type GetName = (name: string) => void // 函数
type Student = UserObj & {idCard: string} // 交叉 -- 不能与其他type属性重合
type Data = [number,string] // 元组
//基本数据类型 联合类型
const str: Types = 'qaz'
const num: Types = 12
// 对象
const obj: userObj = {
name: 'qaz',
age: 12
}
// 函数
let func: GetName = (name: string) => {
}
//交叉类型 类似interface的扩展
const stu: Student = {
name: 'wqq',
age: 12,
idCard: 'qswrfyiweh'
}
// 元组
const arr: Data = [1, '23']
与interface的区别与联系
interface可以多次定义,type不行
interface多次定义 会被视为合并,但是type多次定义的话会报同名错误
interface Student {
name: string;
}
interface Student {
age: string;
}
//不可以对已有属性重新定义别的类型
//此时Student实际{
name: string;
age: string
}
const stu: Student = {
name: "wa",
age: "12",
};
type多次定义
type与interface交叉
interface Person {
name: string;
age: number
}
type Student = Person & {
isCard: string
}
const stu: Student = {
name: 'qaz',
age: 12,
idCard: 'ariehfk'
}
//interface可以extends继承 type 类型
type可以使用in关键字生成映射类型, 但是interface不行
type Types1 = "name" | "address";
type InType = {
[key in Types1]: string;
};
const test: InType = {
name: "12",
address: "23",
};
type 可以使用typeof返回的值作为类型
let str1 = "animal";
type TypeStr = typeof str1;
let strType: TypeStr = "ad";
!修饰符 -- 非空类型断言
function func(value:string){
console.log(value!.length) // 在值后面加上 !修饰符表示确定value是一定有值的, 可以跳过ts在编译阶段对它的检测
}
func('zaq')
类型断言
类型断言可以手动指定一个值的类型
类似于其他语言里的类型转换, 不进行特殊的数据检查和结构,在编译时不是有影响
//第一种 尖括号语法
let str: any = 'qdafdsrfs'
let strLength: number = (<string>str).length
//第二种 as 语法
// 正常
interface NameValue {
name: string
}
interface AgeValue {
age: number
}
function func(params: NameValue | AgeValue) {
if ("name" in params) {
const res = (params as AgeValue).name
console.log(res)
}
if ("age" in params) {
const res = (params as AgeValue).age
console.log(res)
}
}
func({age: 118})
联合类型
联合类型用 |
表示
在定义某些变量时, 一开始没办法确定该变量类型, 可以使用联合类型, 如下代码, 变量满足其中的一个类型就可以
const flag : boolean | string = true
枚举Enum类型
枚举类型可以设置默认值, 如果不设置默认值对应值则为索引
enum className {
math,
english = "English",
chinese = "Chinese",
}
console.log(className.math); // 0
console.log(className.english); // English
console.log(className["chinese"]); // Chinese
注意
如图
math
没有设置默认值, 后面的 english
和chinese
设置了默认值,此时在后面给art
不设置默认值, 此时代码不知道如何递增, 就会出现报错。
但是如果将枚举内的值设置为number
类型,最后一个值会跟着上面一个数据进行递增, 不会报错
enum num {
one,
three = 3,
four
}
console.log(num.four); // 4
//枚举类型还可以通过value查询key值
console.log(num[3]); // three
其他详细相关ts类型可见官网 www.tslang.cn/