从零开始学Typescript|青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第9天
为什么学习Typescript
首先明确JS是一种动态类型的弱类型语言,而TS是静态类型的弱类型语言,正是因为动态类型和静态类型的不同所以TS有很多相较于JS没有的优点。
- 可读性增强:基于语法解析TsDoc,ide增强
- 可维护性增强:在编译阶段暴露大部分错误=>多人合作的大型项目中,获得更好的稳定性和开发效率
- 包含于兼容所有JS特性,支持共存
- 支持渐进式引入于升级
TS环境搭建且使用(VSCode)
- Typescript的环境依赖Node所以电脑上必须要有Node和NPM环境
- 使用在VS code终端上输入npm install typescript -g 全局安装typescript
- 输入tsc ---version可以查看安装的版本
- 创建xxx.ts文件就可以在此文件中写ts代码了
- 最后在VSCode终端输入tsc xxx.ts把ts文件解析成文js文件,这时就会有一个xxx.js文件生成对应xxx.ts文件
TS的基础的语法
基础数据类型
// js中字符串: const q = 'string'
const q: string = 'string';
// js中数字:const w = 1;
const w: number = 1;
// js中布尔值:const e = true;
const e: boolean = true;
// js中null:const r = null;
const r: null = null;
// js中undefined:const t = undefined;
const t:undefined=undefined
对象类型
interface指定一个对象模板,readonly可以约束属性不可以在对象初始化外赋值,xxx?定以可选属性可以不存在,[key: string]:any 可以让外部写值进入对象。
函数类型
函数重载
函数重载:函数名称相同,但是参数的个数或者类型不同
方式一:
方式二:
数组类型
Typescript补充类型
Typescript泛型
在定义一个函数或者是类的时候,有些情况下我们无法确定其中要使用的具体类型(返回值、参数、属性的类型不能确定),此时泛型便能够发挥作用。
不预先指定具体类型,而在使用的时候在指定类型的一种特性
test函数的作用是输入某类型的参数得到相同类型的参数,如果用any就会关闭了TS的自动检查类型功能,而使用泛型就能很好的解决这个问题。
type和interface关键字作用一样,类似于弄一个函数或者类的模板,extends和‘=’表示泛型指向的类型,当指向了某类型,不可以随意赋值
类型别名和类型断言
字符串/数字 字面量
高级类型
联合/交叉类型
当我们为某一个东西编写类型,发现类型声明繁琐,存在较多的重复这个时候我们就可以用到联合/交叉类型大大简化代码
- 联合类型:lA | lB ;联合类型表示一个值可以是几种类型之一
- 交叉类型:lA & lB;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性
类型保护与类型守卫
类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。 摘抄自typescript基础知识:联合类型和类型守卫_innagine的博客-CSDN博客_typescript 联合类型和动态类型
类型保护:
类型守卫:
// 实现函数reverse
// 其可将数组或字符串进行反转
function reverse(target: string | Array<any>) {
// typeof类型保护
if (typeof target === 'string') {
return target.split('').reverse().join('');
}
// instanceof类型保护
if (target instanceof Object) {
return target.reverse()
}
}
// 实现函数logBook类型
// 函数接受书本类型,并logger相关特征
function logBook(book: IBookItem) {
// 联合类型+类型保护=自动类型推断
if (book.type === 'history') {
console.log(book.range);
} else {
console.log(book.theme);
}
}
高级类型
// 实现merge函数类型
// 要求sourceObj必须为targetObj的子集
//类型声明部分:
interface IMerge{
<T extends Record<string, any>>(sourceObj: Partial<T>, targetObj: T): T;
}
type IPartial<T extends Record<string, any>> = {
[P in keyof T]?: T[P];
}
- 索引类型关键字【keyof】,其相当于取值对象中的多有key组成的字符串字面量
- 关键字【in】,其相当于取值字符串字面量中的一种可能,配合泛型P,即表示每个key
- 关键字【?】,通过设定对象可选选项,即可自动推导出子集类型
// 实现函数delayCall类型声明
//delayCall接受一个函数作为入参,其实现延迟1s运行函数
// 其返回promise,结果为入参函数的返回结果
//类型声明部分:
type IdelayCall = <T extends () => any> (func: T) => ReturnType<T>;
type IReturnType<T extends (...arg:any)=>any>=T extends (...args:any)=>infer R ? R : any
- 关键字【extends】跟随泛型出现时,表示类型推断,其表达可类比三元表达式
- 关键字【infer】出现类型推荐中,表示定义类型变量,可用于指代类型