目录
(一)介绍
1.JavaScript 与 TypeScript 的区别
TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。
2.TypeScript的优点
(1)类型安全:Typescript是一种静态类型语言,它要求在编码阶段明确定义变量和函数的类型。这种类型安全可以减少在运行时出现错误的可能性,并提高代码的可读性和可维护性。
(2)代码可读性和可维护性:Typescript的类型注释和严格的类型检查可以使代码更加易于阅读和维护。它还能够使代码更加清晰易懂,从而减少了代码理解和修改的难度。
(3)更好的错误排查:Typescript的类型检查和编译可以在编码阶段发现许多错误,避免了在运行时出现错误。这减少了调试和排查错误的时间和成本。
(4)更好的大型项目支持:Typescript可以更好地支持大型项目的开发。它提供了模块系统、命名空间、接口、枚举等特性,可以使大型项目更加易于管理和维护。
(二)在vue3项目中使用
安装ts:
npm install -g typescript
单文件组件内使用:
<script setup lang="ts">
// ...
</script>
(三)类型声明
类型声明给变量设置了类型,后续使用变量只能存储指定类型的值
1.基础数据类型
(1)string
// string字符型
let str: string = 'csq'
str = '123'
(2)number
// number数字型 可支持十进制、八进制、二进制、十六进制
let num: number = 77
num = 12
let num1: number = 0b10010 // 二进制
let num2: number = 0x18 // 十六进制
(3)boolean
// boolean布尔型
let bool = true
bool = false
(4)null和undefined
// null和undefined
let nu:null = null
let un:undefined = undefined
// 默认禁止将null和undefined赋值给其他数据类型
// let n:number = null
默认禁止将null和undefined赋值给其他数据类型,除非在tsconfig.app.json中添加配置 "strictNullChecks": false
2.引用数据类型
(1)数组array
// 数组
// 1.直接定义
const numArr: number[] = [1, 2, 3]
// 2.泛型定义
const strArr:Array<string> = ['1','2','3']
(2)元组tuple
合并了不同数据类型的对象,数据类型和长度都提前定义好
// 元组tuple
let tarr: [number, string] = [1, '2']
// push时 可以添加number或string类型的数据
tarr.push(3)
tarr.push('4')
(3)对象object
// object对象 非原始数据类型(除number、string、boolean以外的数据类型)
let obj:object = {}
obj = {
a:1
}
obj = [] // 数组是一个对象
obj = new String() // String类实例是一个对象
// 非严格模式才能赋值 否则报错
// obj = null
// obj = undefined
3.any和void类型
(1)any
// any 可定义所有数据类型
let a:any = 1
a = []
a = '123'
let anyArr:any[] = [1,'2',true,{},[]]
(2)void
// void 通常用于函数 返回值为空
function f():void{
console.log(111);
}
// 变量被定义为void后 只能赋值为undefined
let voi:void = undefined
4.使用typeof判断变量的类型
(三)类型推断
在没有显式类型注释的情况下使用类型推断来提供类型信息,
let num = 3; // num被推断为number类型
num = ‘abc’ // 就会报错
这种推断发生在初始化变量和成员、设置参数默认值以及确定函数返回类型时
被推断为any类型的情况:
let g; // 此时变量g被推断为any类型 可以赋任意值
g = 1;
g = [],
g = undefined
(四)联合类型
由两种或多种其他类型组成的类型,表示可能是这些类型中的任何一种的值
只有在对联合的每个成员都有效的情况下才允许操作
// 联合类型
let unite: number | string = 1
unite = 'abc'
// unite = false
function show(a: number | string) {
// toUpperCase函数只能用于string类型,
// a.toUpperCase()
// 必须使用联合类型都能使用的操作
a.toString()
console.log(a);
}
show(123)
show('123')
// show(true)
(五)接口interface
1.对象类型
确定属性:name:string;
可选属性:age?:number;
只读属性:readonly id:number;
任意属性: [propsName:string]:any; 定义了任意属性后,对象变量中的属性个数才可以出现比接口的属性数量多的情况
// 1. ====对象类型====
interface Person {
readonly id: number; // 只能读不能修改
name: string;
age?: number; // ?表示该属性可有可无 number|undefined
// 任意属性 只能在接口里出现一次
// 任意属性 键为string,属性值确定属性和可选属性类型都必须是它的类型的子集
// [propsName:string]:any,
[propsName: string]: string | number | undefined;
}
let p: Person = {
id: 77,
name: 'csq',
age: 18,
sex: 'nv',
weight: 100
}
2.数组类型(不常用)
// 2.====数组类型====
interface Array {
[index: number]: string;
}
let arr: Array = ['1', '2', '3']
3.函数类型
// 3.====函数类型====
interface Fun {
// (传入参数名:参数类型,...):返回值类型
(a: string, b: string): boolean
}
const fun1: Fun = function (a: string, b: string): boolean {
return b.indexOf(a) != -1
}
(六)函数
1.定义函数
// 1.====定义函数====
// 1.函数声明:命名函数
function fun1(a: number, b: number): number {
return a + b
}
// 2.函数声明:匿名函数
let fun2 = function (a: number, b: number): number {
return a + b
}
// 3.函数声明:完整写法
let fun3: (a: number, b: number) => number = function (a: number, b: number): number {
return a + b
}
2.可选参数和默认参数
默认参数: b: string = 'csq'
可选参数:c?: number // 可选参数必须放在所有确定、默认参数之后
// 2.====可选参数和默认参数====
let fun4 = function (a: number, b: string = 'csq', c?: number): string {
return a + b
}
console.log(fun4(7, '77'));
3.剩余函数和函数重载
(1)剩余函数...rest
es6新特性
// 1.剩余函数
function fun5(a: string, b: string, ...rest: number[]) {
console.log(rest);
}
fun5('1', '2', 1, 2, 3)
(2)函数重载overload
// 2.函数重载
// 函数重载声明
function fun6(a: string, b: string): string
function fun6(a: number, b: number): number
function fun6(a: string | number, b: string | number): string | number | void {
if (typeof a == 'string' && typeof b == 'string') {
return a + b //string类型
}
if (typeof a == 'number' && typeof b == 'number') {
return a + b //number类型
}
}
fun6(1, 2)
fun6('1', '2')
// fun6(1,'1')
(七)类型断言
用于手动指定具体的类型
两种使用方法:as 和 尖括号写法<>
因为<>在ts除了表示类型断言外,也可能表示一个泛型。故类型断言更推荐使用as写法
1.将一个联合类型断言为其中一个类型
// 方法1 as 变量 as 类型
let arr = [1, 2, 3]
let result = arr.find((i) => i > 2) as number
result * 7 // 判定可能为数据或undefined
// 方法2 尖括号写法 <类型> 变量
let arr2 = [1, 2, 3]
let result2 = arr.find((i) => i > 2)
let a = <number>result2 * 7 // 判定可能为数据或undefined
2.将父类断言为一个更具体的子类
3.将任何类型断言为any
// 3.将任何类型断言为any
// any类型可以访问任意属性和方法 无论是否存在
(Window as any).abc = '77'
(八)类型别名和字符串字面量类型
1.类型别名
// 类型别名 常用于联合类型
type All = number | string | boolean
let a: All = 1
a = '123'
a = true
2.字符串字面量类型
// 字符串字面量类型 用于指定可选的字符串
type Name = 'csq' | 'zkj' | 'dy'
let b: Name = 'csq'
b = 'dy'
(九)枚举Enum
// ====元组tuple====
let tarr: [number, string] = [1, '2']
// push时 可以添加number或string类型的数据
tarr.push(3)
tarr.push('4')
// ====枚举====
// 使用枚举类型给一组数值赋予名称
// 可以通过名称去拿取值,通过值去拿取名称
// 枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射
// 1,2,3,4
enum NumberType {
one = 2,//手动赋值,没有赋值,第一个参数默认为0,后面递增加一
two = 1,//后面的值如果没有手动赋值,会根据前面的值进行递增加一
three,
four
}
// 手动赋值注意:尽量不要写一些重复的值
console.log(NumberType);
// 枚举项有两种类型:常数项(constant member)和计算所得项(computed member)
// 计算所得项需要放置在已经确定赋值的枚举项之前,后面不能存放未手动赋值的枚举项
enum Color {
red,
blue = "blue".length,
green = 11
}
// 常数枚举是使用 const enum 定义的枚举类型
// 常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员
const enum Obj {
o,
b,
j = 10 + 10
}
console.log(Obj.o);
console.log(Obj.b);
console.log(Obj.j);
// 外部枚举(Ambient Enums)是使用 declare enum 定义的枚举类型
// declare 定义的类型只会用于编译时的检查,编译结果中会被删除
// 声明文件
declare const enum ABC {
a, b, c
}
console.log(ABC.a);