因为介绍了ts的全部类型,所以比较长,各位可以通过目录选择性观看
- typescript类型概述
- typescript 类型注解概念-->监测类型变化
- ts类型注解语法
- ts常用类型
- 原始类型
- 对象类型
- 对象类型_数组类型
- ts新增,联合类型
- ts函数类型
- ts 函数类型 void
- ts 函数类型可选参数
- ts 对象类型
- ts 可选对象属性
- ts 接口
- ts 元组类型
- ts 字面量类型
- ts 枚举类型
- ts any类型
- ts类型别名
typescript类型概述
typescript是JavaScript的超集,ts提供了js所有的功能.并且额外增加了:类型系统
- 所有的js代码都是ts代码
- js有类型(比如,number/string等),但是js不会检查变量的类型是否发生变化,而ts会检查.ts类型系统的主要优势为:可以显示标记出代码中的意外行为,从而降低发生错误的可能性
typescript 类型注解概念–>监测类型变化
为什么要有类型注解?
如下js代码
这段代码在编译器中是不会报错的,尽管很明显,age被赋值了字符串,但字符串并没有toFixed方法,但因为js不会检查变量的类型是否发生变化,所以这里编译器不会报错,但是当我们在未来运行了这段代码,则会报错typeError,变量类型错误在js代码中是很常见的
,所以在编码中我们应该尽量去避免修改变量的类型
但是js中并没有类型检查,光靠人脑去有意识避免这个问题是不现实的,这时候,就需要使用ts了,
ts会检查变量类型的改变 ,如下,当给定age是文本number类型变量时,当你试图给这个number类型变量赋值string时,ts会给出警告
tips: 这里ts报了两个错,上面那个错可以去看我的另一篇文章typescript错误代码 error TS2451: 无法重新声明块范围变量“age”。ts(2451)
这样,当我们在编码的同时,就能发现一些隐藏的bug,这就是上面所说的js不会检查变量的类型是否发生变化,而ts会检查.ts类型系统的主要优势为:可以显示标记出代码中的意外行为,从而降低发生错误的可能性
ts类型注解语法
示例代码
let age :number = 18
- 说明:代码中的:number就是类型注解
- 作用:为变量添加类型约束,比如,上述代码中,约定变量age的类型为number(数值类型)
- 解释: 约定了什么类型,就只能给变量赋值该类型的值,否则就会报错
如下,我们约定变量age类型为numer,然后赋值为字符串’18’时,直接报错
ts常用类型
可以将ts中的常用基础类型细分为两类,1,js已有类型,2ts新增类型
- js已有类型
- 原始类型 : number/string/boolean/null/undefined/symbol
- 对象类型: boject(包括数组,对象,函数等对象) - ts新增类型
- 联合类型,自定义类型(类型别名),接口,元组,字面量类型,枚举,void,any等
原始类型
1 原始类型 number/string/boolean/null/undefined/symbol
特点,简单,这些类型完全按照js中类型的名称来书写
基础类型的使用很简单,在js中怎么用,在ts中就怎么用,是一模一样的
对象类型
对象类型, object(包括,数组,对象,函数等对象)
特点:对象类型,在ts中更加细化,每个具体的对象都有自己的类型语法
对象类型_数组类型
数组类型有两种写法
tips:第一种写法更加简单直观,更推荐第一种写法
当给number[]类型注解的number变量赋值非number的值时,ts会报错
ts新增,联合类型
上面的数组类型写法解决不了一个问题,因为有的数组中,既有字符串,又有数值类型,这个时候就需要用到ts的新增类型联合类型了
代码示例如下
tips | 竖线在ts中叫做联合类型,由两个或多个其它类型组成的类型,表示可以是这些类型中的任意一种,
注意:这是ts中联合类型的语法,只有一根竖线,不要和|| 或符号 搞混了
联合类型也有两种语法
let united1: (string | number)[] = [1, 'a', 2, 'b', 3, 'c']
let united2: Array<string | number> = [1, 'a', 2, 'b', 3, 'c']
依然推荐第一种,因为第一种写起来简单,不过我其实更喜欢第二种,因为酷~!!!
ts函数类型
函数的类型实际上指的是:函数参数和返回值的类型
为函数指定类型的两种方式:
- 单独指定参数,返回值的类型
- 同时指定参数,返回值的类型
语法:如下
//单独指定参数,返回值的类型
//直接在函数参数后面:添加函数类型,并在小括号后面添加返回值类型
function add1(a: number, b: number): number {
return a + b
}
//同时指定参数,返回值类型
const add2: (a: number, b: number) => number = (a, b) => a + b
//当函数作为表达式时,可以通过类似箭头函数形式的语法来为函数添加类型
//注意,这种形式的写法,只适用于函数表达式
//还有一件事,后面的函数表达式里参数名称不必和指定参数类型时的参数名称一致
//也就是说下面这句表达式是成立的
//const add: (a: number, b: number) => number = (aa, bb) => aa + bb
//就是不易于理解
如下代码示例
当试图给代码传入非number参数时报错
如下,当试图返回字符串类型的值时报错
ts 函数类型 void
如果函数没有返回值,那么函数返回值类型为void
如下
function sayHi(name: string): void {
console.log(`Hi, ${name}`)
}
ts 函数类型可选参数
使用函数实现某个功能时,参数可以传也可以不传,这种情况下,在给函数参数指定类型时,就用到了可选参数了,
比如,数组的slice方法,可以clice()也可以slice(1),还可以slice(1,3)
function mySlice(start?: number, end?: number): void {
console.log(`${start} ${end}`)
}
//可选参数:在可传可不传的参数名称后面添加?(问号)
//可选参数只能出现在参数列表的最后,也就是说,可选参数后面不能再出现必选参数
示例
ts 对象类型
js中的对象是由属性和方法构成的,而ts中对象的类型就是在描述对象的结构(有上面类型的属性和方法)
俺对象类型的写法
let person: { name: string, age: number, sayHi(name: string): void } = {
name: 'Tom',
age: 20,
sayHi(name: string) {
console.log(`Hi, ${name}`)
}
}
tips
1. 直接使用{}来描述对象结构,属性采用属性名:类型的形式,方法采用方法名():返回值类型的形式
2. 如果方法有参数,就在方法名后面的小括号中指定参数类型(比如sayHi(name: string): void })
3. 在一行代码中指定对象的多个属性类型时,使用;(分号)来分隔,也可以使用逗号分隔,也可以使用换行符来分隔
4. 如果一行代码只指定一个属性类型.(通过换行来分割多个属性类型)可以去掉;分号
5. 方法的类型也可以使用箭头函数形式(比如{sayHi:()=>void})
示例如下
ts 可选对象属性
对象的属性和方法,也是可以可选的,此时就要用到可选属性了
可选属性的语法与函数的可选参数一致,都是使用?(问号)来修饰
let person: {
name: string; age?: number //分号分隔
sayHi(name: string): void //换行符分隔
} = {
name: 'Tom', //当age类型前添加了问号时,缺少age属性赋值,并不会报错
sayHi(name: string) {
console.log(`Hi, ${name}`)
}
}
ts 接口
当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的
示例如下
当一个对象类型被多次使用时,可以看到,很明显代码有大量的冗余
let personTom: { name: string, age?: number, sayHi(name: string): void } = {
name: 'Tom',
sayHi(name: string) {
console.log(`Hi, ${name}`)
}
}
let personJack: { name: string, age?: number, sayHi(name: string): void } = {
name: 'Tom',
sayHi(name: string) {
console.log(`Hi, ${name}`)
}
}
这个时候可以将这个对象定义为接口,以进行复用,可以看到,这样代码就少了很多冗余
interface Person {
name: string
age?: number
sayHi(name: string): void
}
let personTime: Person = {
name: 'time',
sayHi(name: string) {
console.log(`hello ${name}`)
}
}
let personJohn: Person = {
name: 'John',
sayHi(name: string) {
console.log(`hello ${name}`)
}
}
- 使用interface关键字来声明接口
- 接口名称(比如,此处的Person)可以是任意合法变量名称
- 声明接口后,直接使用接口名称作为变量的类型
- 因为每一行只有一个属性类型,因此,属性类型后没有分号或逗号
因为篇幅原因,这里就简单介绍一下typescript 接口类型,更详细的可以看这里typescrip接口 interface详解,以及ts实现多态
ts 元组类型
元组概念:
在 TypeScript 中,元组可以通过在方括号内用逗号分隔的元素列表来定义。每个元素可以具有不同的类型,而元素的顺序是固定的。例如,我们可以定义一个元组类型来表示一个点的 x 和 y 坐标
场景如下
在地图中,使用经纬度坐标来标记位置信息,
可以使用数组来标记坐标,那么,该数组中就只有两个元素,并且这两个元素都是数值类型
let position: Array<number> = [12.3456, 23.4567]
但是使用数值数组的缺点是,不严谨,因为该类型的数组中可以出任意多哥数字,如下
let position: Array<number> = [12.3456, 23.4567, 34.5678, 45.6789, 56.7890]
这时候,我们应该用更好的方式:元组(tuple)
元组类型是另一种类型的数组,它确切的知道包含多少哥元素,以及特定索引对应的类型
let positionTuple: Array<number| number> = [12.3456, 23.4567];
tips: 元组类型可以确切的标记出有多少个元素,以及每个元素的类型
如下,当尝试给元组positionTuple赋值第三个数值时,报错
tips:别用Array<number| number>这种方式声明元组,有些问题,它不会检查元组长度,而且ts元组竟然可以使用push方法,离谱离谱
有时间研究一下,这篇文章不对此做过多介绍
ts 字面量类型
ts字面量介绍
TypeScript(TS)中的字面量类型是一种特殊的数据类型,用于表示固定的值或一组有限的值。这种类型在某些情况下非常有用,例如在定义枚举类型或特定于应用程序的常量时。
示例如下
let str1 = 'hello world'
const str2 = 'hello world'
上面的代码通过ts类型推论机制,我们可以看到,两个变量类型是不同的
- str1的变量类型是:string
- str2的变量类型是:‘hello world’
这是因为str1是一个变量,(let)可以是任意的string类型数据,额,可以是任意类型字符串,所以变量类型是string
而str2是一个常量(const) 它的值不能发生变化,所以只能是’hello world’,所以它的类型为’hello world’
也就是说,此处的’hello world’就是一个字面量类型,
某个特定的字符串可以作为ts中的类型, 如下
let str1 = 'hello world'
const str2 = 'hello world'
//将hello world作为类型
let str3: 'hello world' = 'hello world'
当然,除了字符串外,任意的js字面量都能当作类型使用
let str1 = 'hello world'
const str2 = 'hello world'
let str3: 'hello world' = 'hello world'
let age: 18 = 18
let isChild: [1, 2] = [1, 2]
篇幅原因只做介绍,更多内容请移步typescript字面量类型也是我写的
ts 枚举类型
理解了上面的字面量类型和联合类型,那么理解枚举类型就很简单了,因为枚举类型功能就类似于字面量类型+联合类型组合的功能,也表示一组明确的可选值
枚举:定义一组命名常量,它描述一个值,该值可以是这些命名常量中的一个
定义枚举
枚举类型在TypeScript中用 enum 关键字定义。下面是一个简单的枚举例子:
在这个例子中我定义了一个名为 Direction 的枚举类型,它有四个可能的值:Up,Down,Left 和 Right。我们可以使用这些值来表示一个角色在屏幕上的方向。
enum Direction {
Up,
Down,
Left,
Right
}
function move(direction: Direction) {
//... your code here
}
- 使用enum关键字定义枚举
- 约定枚举名称,枚举中的值,枚举中的多个值之间通过,逗号隔开
- 枚举名称,以及枚举中的值应该由大写字母开头
- 枚举可以直接用作类型注解
篇幅原因只做简单介绍,更详细的讲解内容请移步ts 枚举类型原理及其应用详解
ts any类型
any 是一种特殊的数据类型,它表示任意类型。使用 any 类型声明的变量可以接受任何类型的值,包括字符串、数字、对象、函数等等。
使用 any 类型的变量会失去 TypeScript 的类型安全性,因此应该尽量避免使用。但在某些情况下,例如在处理外部数据或与非 TypeScript 代码交互时,any 类型可能会非常有用。
示例如下
下面段ts代码中,person对象使用any类型修饰,导致将person对象重新赋值为1时,ts放弃了做类型检查,这将可能导致未来代码出现异常错误
所以我们应当尽量避免使用any类型,除非临时使用any来避免书写很长很复杂的类型
其它隐式具有any类型的情况
- 声明变量不提供类型也不提供初始值,
- 函数参数不加类型
tips: 因为不推荐使用any所以上面两种情况都应该提供值,来避免隐式出现any类型
ts类型别名
类型别名(自定义类型):为任意类型起别名
使用场景:当同一类型(复杂)被多次使用时,可以通过类型别名,简化该类型的使用
tips :
1. 使用type关键字来创建类型别名
2. 类型别名(比如此处的StrNumArrary)可以是任意合法的变量名称
3. 创建类型别名后,直接使用该类型别名作为变量的类型注解即可