嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,爱思考,爱总结,爱记录,爱分享 🏹,欢迎关注我呀 😘 ~ [微信号:
yk2012yk2012
,微信公众号:ykyk2012
]
「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」
今天来介绍typescript的类型系统,主要是学习一些语法
参考链接:
- 官网:www.typescriptlang.org/
- 中文网:www.tslang.cn/ (貌似很久没维护了)
- 掘金小册: juejin.cn/book/684473…
- 书籍:《深入理解TypeScript》 jkchao.github.io/typescript-…
- B站尚硅谷视频:www.bilibili.com/video/BV1Xy…
1. 起步
- 类型声明是TS非常重要的一个特点
- 通过类型声明可以指定TS中变量(参数、形参)的类型
- 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
- 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
我们先来看看,TypeScript给变量指定类型的语法(类型注解)是什么
// 声明一个变量
let 变量: 类型
// 声明一个变量并给其赋值
let 变量: 类型 = 值
// 声明一个函数
function yk(参数: 参数类型): 函数返回值类型{
//...
}
这里我们可以看到,就是在变量后面就一个冒号,然后标识其类型就可以了
2. 类型
下面我们就来介绍介绍,TypeScript中到底有哪些类型
学过js你认识的类型:boolean
、number
、string
、undefined
、null
、symbol
、bigint
、object
你可能不认识的类型:void
、any
、unknown
、never
我们后面会详细的介绍这些你可能不认识的类型
2.1 变量
如果我们在声明变量指定类型后,之后如果给变量赋值为其他类型的值,编辑器会报错,如图所示
let n: number = 1
n = 3
n = '1' // 编辑器报错,不能将字符串赋值给number类型的变量
2.2 自动类型判断
- TS拥有自动的类型判断机制
- 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
- 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
那都可以省略了,还要自己写类型干嘛呢? 事实上,显式的写类型更有优势的地方是在函数定义的时候
2.3 函数
我们先回顾下用js声明一个函数的特点:js中的函数是不考虑参数的类型和个数的
function sum(a, b){
return a + b
}
console.log(sum(1, 2)) // 3
console.log(sum(1, '2')) // '12'
而用ts定义
function sum(a: number, b: number): number{
return a + b
}
console.log(sum(1, 2)) // 3
参数数量也有限制
因为TS有类型推断,所以函数的返回值可以不用显式指定
function sum(x: number, y: number) => x + y
2.4 类型详解
基本类型我们就不详细谈了,我们来说说TS中一些特殊的类型
void
相信熟悉Java或者C的同学应该对void
也不会陌生,当函数没有返回值的时候,定义函数的返回值类型就是void
其实我们知道,在JavaScript中,如果定义一个函数不写返回值,那么它默认是返回 undefined
的~
什么都不返回
function fn(): void {
}
只写一个return
function fn(): void {
return
}
返回一个undefined
function fn(): void {
return undefined
}
我们返回一个null
也是可以的
function fn(): void {
return null
}
除了以上的几种情况,其他情况都是不行的
也就是说只有null
和undefined
可以赋给void
其实在JS中void
是一种操作符,可以让任何表达式返回undefined
void 0 // undefined
为什么要这样呢,因为undefined
在JS中不是一个保留字,可以通过声明变量来覆盖它
any
any
表示的是任意类型,一个变量设置类型为 any
后,相当于对该变量关闭了TS的类型检测。
隐式any
:如果只声明变量不指定类型也不给变量赋值,变量就是any
类型的
当把any
类型的变量可以赋值给其他类型的变量,不会报错
let a
let b: any
a = 1
a = '1'
b = '1'
b = 1
let c:string = '123'
c = b
any
类型是多人协作项目的大忌,很可能把Typescript变成AnyScript,通常在不得已的情况下,不应该首先考虑使用此类型。
unknown
开发的时候有些变量就是事先不知道的类型怎么办呢?可以使用unknown
unknown
与any
的区别就是,将unknown
类型变量赋值给其他任意类型的变量时,会报错
可以这样理解:unknown
类型的变量就是类型安全的any
,不能直接赋值给其他类型的变量
需要在赋值之前做好类型判断 (这叫缩小类型范围)
if (typeof b === 'string') {
c = b
}
或者这样写 【类型断言】(相当于告诉解析器b就是一个string类型的变量)
c = b as string
或
c = <string>b
never
never
表示永远不会返回结果
- 报错
function error(): never{
throw new Error('报错了!')
}
- 死循环
function endless(): never{
while(true) {}
}
对象
一般来说,我们对于对象的类型检查一般是检查对象中有哪些属性,属性是什么类型。
可以用{}
来指定对象中可以包含哪些属性 语法:{属性名: 属性类型, ...}
属性多了少了都不行
可选属性,在属性名后面加一个 ?
let obj: {name: string, age?: number}
obj = {name: 'yk', age: 18}
obj = {name: 'yk'}
如果后续属性不确定叫什么名字,也不确定是什么类型,那么可以这样写[propName: string]: unknown
// 定义对象结构
let obj: { name: string, [propName: string]: unknown }
obj = {name: 'yk', age: 18, gender: 'male'}
函数
因为function
是关键字,所有这里用Function
来声明函数
let fn: Function
和对象一样,我们一般会限制函数有几个参数,参数的类型,返回值的类型,所以就可以以一种类似箭头函数的方式来声明一个函数类型的变量
// 定义函数结构
let fn: (a: number, b: number) => number
数组
比较常用的就是这种方式: 在元素类型后面接上 []
:
let arr: number[] = [1, 2, 3]
let arr2: string[] = ['y', 'k']
还有一种是使用泛型(后面会说什么是泛型):
let list: Array<number> = [1, 2, 3]
let list2: Array<string> = ['y', 'k']
let list: Array<number | string> = [1, 2, 3, 'yk']
元组 Tuple
元组是TS新出的类型,表示固定长度的array
元组中包含的元素,必须与声明的类型一致,而且不能多、不能少,甚至顺序都不能不一样
字面量
也可以使用字面量去指定变量的类型,这相当于给他设置成了一个常量
let a: 10
a = 10
2.5 联合类型
可以给一个变量定义一个联合类型,类型名之间用 |
隔开
这个时候,字面量类型就有用了
let gender : "male" | "female"
此时gender
只能被赋值成两个值
2.6 类型别名
这个时候,如果一个类型的字面量类型选择过多,重复编写就比较麻烦,这就可以使用类型别名
type myType = 1 | 2 | 3 | 4 | 5
let i: myType
let j: myType
let k: myType
k = 2
可以通过类型别名来定义函数参数类型结构
type fn = (x: number, y:number) => number // 这里fn表示类型
这个和之前定义函数结构是类似的
let fn: (x: number, y:number) => number // 这里fn表示值
但是使用类型别名使用起来就是这样
let fun: fn = (x, y) => x + y
2.7 总结
3. 类型断言
有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却并不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式:
第一种
let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;
第二种
let someValue: unknown = "this is a string";
let strLength: number = (<string>someValue).length;
最后,欢迎关注我的专栏,和YK菌做好朋友