TypeScript 初识
介绍
他是基于JavaScript之上的语言的编程语言,在TypeScript官网写道,TypeScript是JS的超集,他重点解决了JavaScript自有的类型系统不足,通过使用TypeScript提高代码可靠度。
- 缺点:语言本身多了很多的概念,并且项目周期短,且项目小的,会增加开发的成本
强类型与弱类型语言(类型安全)
-
从类型安全角度说,编程语言被分为强类型与弱类型语言
-
- 【弱类型语言的概念】在弱类型语言当中,隐式转换常常发生
- 【强类型语言的概念】在语言的层面上,不允许进行隐式转换
静态类型与动态类型(类型系统)
-
从类型系统上进行语言的区分
-
- 【静态类型】一个变量被声明的时候,类型就已经确定了,在变量声明过后,是不允许被改变的
- 【动态类型】正在代码执行的过程中,类型才能被确定,而且变量是可以随意进行修改的
JavaScript类型系统的特征
-
为什么JavaScript不能被设计成强类型/静态类型的语言,跟JavaScript早年被开发出来有关联
-
- 在早前没想到现在应用的广泛,早前应用的很简单
- JavaScript是一门脚本语言,脚本语言的特点是不需要进行编译的环节的,直接在运行环境当中进行运行
安装与调试
-
通过使用npm进行全局安装【npm install typescript -g】,如果不选择在全局安装TypeScript的话可以在项目里面通过npn进行安装
-
查看ts的版本【tsc -v】
-
编译**.ts**文件【tsc xxx.ts】
-
在开发的时候,不会经常的去保存完再去运行指令去编译TS文件,通过命令的方式,去侦听某一个TS文件,保存的时候,自动编译TS文件【tsc xxx.ts -w】
体验TypeScript
- 体验typescript的类型校验,并且如果类型校验错误,在编译的过程中就提示错误
function sum(a:number,b:number) {
return a+b
}
console.log(sum(5,6))
- 在特殊的函数操作的时候,不能直观的看出调用函数要传递什么参数,可以采用类型推断,明确知道在使用的时候,该传递什么类型的数据
TypeScript的类型推断
String , Number , Boolean的类型推断
- 当不明确需要设置的数据类型的时候,TS会分析,推断你需要设置的数据类型,当鼠标悬停到 b 变量的时候,会提示 b 是string数据类型 【类型推断与字符串相同的有,number,boolean】
let a = 'a是string类型'
a = "string"
- 当遇到不确定 any 类型的提示的时候,可以设置函数必须传递的数据类型是啥,在函数以及对象的时候,因为没有明确的值 TS 无法进行类型推断,所以需要指定参数类型
function sum(a: number,b :number) : string { /* 在设置类型的时候,还可以指定函数返回值的数据类型 */
return '计算结果是:' + a + b
}
sum(5,6)
Array的类型推断
- 普通的数据类型推断,数组的推断也是有所不同的,需要注意的是,当定义一个有值的数组时候,鼠标悬停到数组变量上,会显示【 let arr : (string | number)[ ] 】,他代表的是,这个变量是数组类型,并且里面只能去添加字符串与数值类型的‘值’。像数组中添加布尔类型是不可以的
- 通过设置类型,允许像数组中添加拿一些类型的操作
let arr: (string | number | boolean)[] = []
arr.push('100')
对象的类型推断
- 对于对象里面的数组,数组里面他必须是一个对象类型,并且对象类型内部的值,也有具体的类型
- 在修改或者是添加的时候,系统会自动提示,对象里面某一个属性的类型
TypeScript明确类型设置
对基本数据类型的明确设置
let str: string = 'css'
let num: number = 100
let bool: boolean = true
let arr: (string | number)[] = []
对象的类型的明确设置
- 限定对象的值的类型
let obj: { name: string,age: number }
obj = { name: "小明",age: 18 }
- 如果在设置对象属性的时候,有一个参数是可选的,可以传递,也可以不传递,但是在类型设置的时候,需要给属性设置数据类型,如何进行设置
let obj: {name: string , lesson: {}[] , url?: string}
通过类型设置的时候,在后面通过使用 ‘?’来设置这个参数是可选的,在创建对象的时候,可以不设置这个属性
let obj: {name: string,age:number,url? : string,lesson: {}[]}
obj = {
name: '小明',
age: 18,
lesson: [
{
name: '小红',
age: 18
}
]
}
组合类型在TypeScript的声明
let a: number | string | true
let arr: (string | number | true)[]
TypeScript的配置文件
- 初始化一个TS的配置文件【tsc --init】
- 运行文件并可以对整个文件内部的TS文件进行检测编译 【 tsc -w 】
any,unknown
any类型
- 在TypeScript里面,不推荐去使用any类型,使用any类型意味着所有的数据类型都可以进行设置,如果没有特殊的情况下,就不要使用any类型,在定义数组的时候,如果里面的数据类型比较多,可以去使用any类型
let arr: any[] = []
unknown类型
- 在TypeScript里面,unknown类型他没有明确的类型,在TypeScript里面,不知道他的类型是什么,如果使用了类型为unknown的的变量,去赋值给另一个变量,这时候就需要使用类型断言,告诉其他变量,我的这个变量是什么类型的
let a: unknown = 'unknown'
let str:string = a as string /* as告诉前面的变量,我的这个数据类型是什么 */
- 在某些时候,想要将一个类型转换成另一个数据类型,来赋值给另一个变量,这时候可以使用类型断言,然后将unknown类型作为中间类行,对数据进行转换
let str:string = '99'
let num: number = str as unknown as number
void,never
void类型
- 这个数据类型,可以是空,可以是null,还可以是undefined,并且void类型是不可以被赋值成其他数据类型
- 使用场景多用于函数的返回值
function sum(): string | void { /* 返回值是undefined,函数不明确的返回值 */
return 'typescript'
}
console.log(sum())
never类型
- never类型他没有任何值,使用的场景函数身上,当函数执行错误,或者是并没有执行结果会使用never类型,或者是函数执行不到最后
function sum(): never {
throw new Error('类型错误')
}
console.log(sum())
null,undefined
- 在声明【null,undefined】类型的数据的时候,他们的值必须分别是【null,undefined】,但是需要注意的,null于undefined可以做为其他类型数据的值。
let n: null = null
let un: undefined = undefined
/------------------------------------/
let str: string = 'typescript'
str = undefined
console.log(str)
- 二者多用于函数的返回值
function sum(): null | undefined | string {
return 'typescript'
}
console.lgo(sum())
函数在TypeScript中使用
函数在TypeScript中声明
- 函数类型可以指定类型后,在进行赋值,也可以使用类型断言,将函数赋值给另一个变量
let sum =()=> {} // 普通声明
let sum:Function;
sum =()=> {}
let a:string = fun as unknown as string // 使用类型断言,将函数类型转换赋值给字符串类型‘a’
函数参数的声明
function sum( a:number, b:number, redio?: number) {
return a + b
}
sum(2,5)
1. 普通的设置函数参数的方式 ‘a: number’
2. 如果有一个参数是可以传递或者是不传递 ‘redio?:number’
也就是在参数的后面拼接‘?’代表这个参数可以传或者是不传递
3. 可选参数设置默认值 ‘redio: number = 0.6’
函数返回值的修饰
- TypeScript非常欠发达,它会根据函数的参数的类型,或者是根据函数运行的结果,推断函数的返回值类型。
- 普通函数的返回值
1. 第一种情况,函数在有返回值的情况下,设置函数返回值的类型
function fun(a:number,b:number): string { /* 指定函数的返回值 */
return `${a+b}`
}
console.log(fun(5,6));
2. 第二种情况,一些特殊特殊的时候函数是没有返回值的,这时候函数的返回值是一个‘void’类型
function fun():void {
console.log('函数没有返回值')
}
- 箭头函数的返回值设置
let fun =():vido => console.log('箭头函数的返回值,并没有')
使用type对函数参数的声明
- 在图中可以看到,两个函数的参数类型定义是相同的,这时候可以去使用type对参数进行统一的定义
函数的解构定义
1. 对函数的简单限制,并不能限制内部的内容,这样只能对函数自身类型的限制,不限制参数以及返回值
let fun: Function fun =()=> {} /* fun被赋值为函数,其他类型是不可以的 */
2. 更严格的类型定义,包含返回值以及参数的类型
let fun:(a:number,b:number) => number
/* ‘fun’函数的具体实现,并且注意的是, 具体实现可以不与定义的函数参数类型名字一样,也是可以的 */
fun =(x,y)=> {
return x + y
}
使用type对函数的描述
- **使用type对函数进行描述,也就是定义了一个函数类型,然后通过这个函数类型去约束另一个函数,**被约束的变量就必须是一个函数
type userType = {name: string ,age: number}
type userAddFun = (user:userType) => string
let addUser: userAddFun = (user:userType):string => {
return `${user.name} ${user.age}`
}
console.log(addUser({name: 'type',age: 25}));
元组tuple
- 元祖类型他与数组很相似,但是与数组不同的是,元组类型里面的数据,不限制类型的元素,但是每一个元素必须对应数组中类型的位置
1. 元组的声明
let tuple: [number,string] = [1,'11']
注意! 如果你要去修改元组里面的值,必须修改成对应类型的数据
tuple[0] = 'str' // 报错
tuple[0] = 99 // 正常打印
2. 数组的声明
let arr: (number | string | boolear)[] = []
- 数组与元组的类型推断是有所不同的
let arr: readonly [] // 元组
let tuple: [number, string] // 元组
let arr: number[] // 数组