TypeScript笔记
1 认识TypeScript
TypeScript的出现是为了解决JavaScript不进行类型检测的问题
TypeScript是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码。
TypeScript是JavaScript的一个超集
TypeScript编译环境
npm install typescript -g
tsc --version
tsc index.ts将.ts文件编译为.js文件
tsc --watch index.ts使用tsc命令的监视模式,只要重新保存了ts文件,就会自动调用tsc将ts文件转换为js文件TypeScript运行环境 node.js
npm install ts-node -g
npm install tslib @types/node -g
ts-node index.ts直接通过ts-node运行.ts文件
注释有单行注释和多行注释;分号同JS,可写可不写
2 数据类型
13种类型,分为原始类型(基本数据类型)和对象类型(复杂数据类型)。常见的基本数据类型有5个。number、string、boolean、undefined、null
2.1 number
不区分整型和浮点型,支持二进制,八进制,十进制,十六进制
1 | num = 100; // 十进制 |
2.2 boolean
只有两个值:true和false
1 | let flag: boolean = true; |
2.3 string
推荐写单引号,而非双引号。加号两边只要有一边是字符串,就执行字符串拼接;除加号外,其他算术运算符只应该跟数字类型一起使用。在字符串前面添加+号,可以将string转化为number类型
1 | let message: string = "hello world"; |
支持ES6的模板字符串来拼接变量和字符串:
1 | const name = "why"; |
2.4 Array类型
两种形式:
1 | const names: string[] = ["abc", "cba", "cba"]; |
如果添加其他类型到数组中将会报错
2.5 object
object对象类型可以用于描述一个对象:
1 | const myInfo: object = { |
但是从myinfo中我们不能获取数据,也不能设置数据
2.6 Symbol
在ES5中,如果我们是不可以在对象中添加相同的属性名称的。通常我们的做法是定义两个不同的属性名字:比如identity1和identity2。
但是我们也可以通过symbol来定义相同的名称,因为Symbol函数返回的是不同的值:
1 | const s1: symbol = Symbol("title"); |
2.7 null和undefined
共同特点:只有一个值,值为类型本身
1 | let n: null = null; |
undefined和null的区别:
- undefined:表示声明但未赋值的变量值(找不到值)
- null:表示声明了变量并已赋值,值为null(能找到,值就是null)
2.8 any
在某些情况下,我们确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们可以使用any类型
any类型有点像一种讨巧的TypeScript手段:
我们可以对any类型的变量进行任何的操作,包括获取不存在的属性、方法;
我们给一个any类型的变量赋值任何的值,比如数字、字符串的值;
1 | let a: any = "why"; |
如果对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候我们可以使用any: 包括在Vue源码中,也会使用到any来进行某些类型的适配;
2.9 unknown
描述类型不确定的变量
1 | function foo(): string { |
2.10 void
通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型。我们可以将null和undefined赋值给void类型,也就是函数可以返回null或者undefined
2.11 never
表示永远不会发生值的类型,比如一个函数:
- 如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西吗?
- 不会,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型;
1 | function loopFun(): never { |
2.12 tuple
元组类型
1 | const tInfo: [string, number, number] = ["why", 18, 1.88]; |
tuple和数组的区别:
- 首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组中)
- 其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
1 | const info: (string|number)[] = ["why", 18, 1.88] |
应用场景:通常可以作为返回的值
1 | function useState<T>(state: T): [T, (newState: T) => void] { |
3 数组
3.1 基本使用
第一种方式
1 | let names:string[] = ['sjx', 'sjk', 'syf'] |
第二种方式(不推荐)
1 | let names:string[] = new Array('sjx', 'sjk', 'syf') |
功能与[]相同,但是更加繁琐
3.2 数组长度和索引
数组长度
数组长度:表示数组中元素的个数,通过数组的length属性来获取
数组索引
从0开始,最大索引=数组长度-1
3.3 往数组的后面添加新值
1 | newArr[newArr.length] = 1; |
4 函数
typescript允许我们指定函数的参数和返回值的类型
4.1 函数的参数类型
声明函数时,可以在每个参数后添加类型注解,以声明函数接受的参数类型
4.2 函数的返回值类型
和变量的类型注解一样,我们通常情况下不需要返回类型注解,因为TypeScript会根据 return 返回值推断函数的返回类型
4.3 匿名函数的参数
匿名函数与函数声明会有一些不同:
当一个函数出现在TypeScript可以确定该函数会被如何调用的地方时;
该函数的参数会自动指定类型;
1 | const names = ["abc", "cba", "nba"]; |
我们并没有指定item的类型,但是item是一个string类型:
这是因为TypeScript会根据forEach函数的类型以及数组的类型推断出item的类型;
这个过程称之为上下文类型(contextual typing),因为函数执行的上下文可以帮助确定参数和返回值的类型;
4.4 对象类型
对象类型做函数参数
函数接受的参数是一个对象,属性之间可以使用,和;来分割;每个属性的类型部分也是可选的,如果不指定,那么就是any类型
1 | function printCoordinate(point: {x: number, y: number}) { |
可选类型
对象类型也可以指定哪些属性是可选的,可以在属性的后面添加一个?:
1 | function printCoordinate(point: {x: number, y: number, z?: number}) { |
可选类型可以看作是类型和undefined的联合类型
1
2
3
4
5
6
7
8
9
10 function print(message?: string) {
console.log(message)
}
print()
print("coderwhy")
print(undefined)
// error
print(null)
4.5 联合类型
TypeScript的类型系统允许我们使用多种运算符,从现有类型中构建新类型
第一种组合类型的方法——联合类型
- 联合类型是由两个或者多个其他类型组成的类型
- 表示可以是这些类型中的任何一个值
- 联合类型中的每一个类型被称之为联合成员
1 | function printId(id: number|string) { |
一般情况下需要缩小联合
1 | function printId(id: number|string) { |
4.6 类型别名
1 | type Point = { |
1 | type ID = number|string |
5 对象
5.1 对象概述
一组相关属性和方法的集合,并且是无序的
5.2 接口
对象的类型注解
语法说明
1 | let person: { |
与对象的区别:键值对中的值是类型(这是对象的类型注解);多个键值对之间使用分号分隔,并且分号可省略;接口的名字后面为冒号而非赋值。类型注解后,定义对象时不需要写let,防止变量的重复声明
对象方法的类型注解
参数,返回值
1 | let p1: { |
接口的使用
直接在对象名称后面写类型注解的坏处:代码结构不间接;无法复用类型注解
接口:为对象的类型注解命名,并为你的代码建立契约来约束对象的结构。interface表示接口,接口名称约定以I开头,推荐使用接口来作为对象的类型注解
1 | interface IUser { |
5.3 内置对象
数组对象
属性:length
方法:push、forEach(遍历数组)、some(遍历数组,查找是否有一个满足条件的元素(如果有,就可以停止循环))
1 | let songs: string[] = ['五环之歌', '探清水河', '晴天'] |
上面的例子中forEach方法的参数是一个函数,这种函数也称为回调函数。forEach方法的执行过程:遍历整个数组,为数组的每一项元素,调用一次回调函数
1 | let has: boolean = nums.some(function(num)) { |
在typescript中,定义变量时可以不指定类型
情况一:
1
2 let num = 1
num = '' // 代码会报错,第一行代码发生了类型推论情况二:
1
2
3 let num
num = 1
num = '' // 不发生类型推论,不会报错推荐书写typescript代码时,能省略类型注解的地方就省略,充分利用TS类型推论的能力,提升开发效率
- 本文标题:Typescript笔记
- 本文作者:馨er
- 创建时间:2022-05-01 21:18:03
- 本文链接:https://sjxbbd.vercel.app/2022/05/01/25b99359dc7b/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!