1、使用TypeScript:html
背景:前端
RollBar是一个网页检测的网站,该网站统计了2018年前端项目抛出异常的种类,其中有七种是type error,即类型错误。异常最多的类型是读取了undefined变量的属性node
而这个问题能够经过TS定义严格的数据类型解决:webpack
type TypeApple = { name: string, count: number }
/** @type {TypeApple} */ const apple = { name: 'foo', count: 100 }
TS和VSCode(一款IDE)结合,也能够实现静态类型检测,只不过使用注释形式,同样支持tsconfig.json
和自定义Typing。git
如何使用TS:github
npm install –g typescript
tsc –v
1.新建 .ts 后缀的文件 —— 2.编写知足 ts 风格的代码——3.使用tsc编译ts文件(最后获得的仍是js文件)web
TS主要语法:typescript
1.类型系统:npm
2.接口编程
在TypeScript中,接口的做用是对值所拥有的结构进行类型检查,接口是一种结构约束。同时提供了一种方式去抽象代码。
3.类
js自己并非一种OOP(面向对象编程)的语言,并无类这样一个概念。JS的对象使用原型链进行继承和扩展。ES6中提供的Class关键字只是一个语法糖,让你用面向对象的方式编写类,底层仍是原型链的连接。
继承,以某个类为父类,继承全部的属性和方法,同时能够进行扩展和重写方法:
a.protected 在类自身的内部能够访问,子类能够访问,外部没法访问;
b.private 仅可在类自身的内部进行访问,子类没法访问,外部没法访问。
抽象类。抽象类没法实例化,只能做为其余类的基类。不一样于接口,抽象类能够描述类的实现细节。抽象方法在派生类中必须实现。
4.函数:
TS函数参数和返回值的类型指定以及函数重载。
指定了函数的参数类型和返回结果,函数的功能就比较特定了。可是js毕竟是动态类型的函数,js内根据参数类型不一样返回不一样的类型比较常见,因此ts提供函数重载功能
5.断言:
注意事项:
1.文件声明(开发环境对TS文件的支持):规定namespace+第三方库+管理工具+声明文件
2.项目工程化:
a.使用webpack的文件变更检测机制,自定义启动脚本(当检测到文件发生变化时从新编译和运行入口js);
b.使用ts-node和pm2,更改pm2的启动配置,让pm2使用ts-node直接运行ts的入口文件。
3.tsconfig.json相关:
相似eslint,例如是否容许 使用 any 类型, 是否容许存在未使用的变量等等。
https://www.tslang.cn/docs/handbook/compiler-options.html
https://www.tslang.cn/docs/handbook/error.html
2、细化模块分类:
通常状况下,模块都会有耦合。但若是耦合度太高,每每是由于模块没有细分到位。若是细化模块?举例,假若有一个模块叫Operation
,里面既包含操做相关逻辑,也有操做面板逻辑。随着业务发展,操做面板逻辑愈来愈多。咱们彻底能够将操做面板逻辑单独抽成一个模块OperationPanel
。
化繁为简:
//1.If的使用简单粗暴,容易理解。 if ( animalType === 'dog' ) { console.log( 'Wang!' ) } else if ( animalType === 'cat' ) { console.log( 'Miao!' ) } else if ( animalType === 'bird' ) { console.log( 'Jiu!' ) } //2.Switch能够看作是If的简化。 switch ( animalType ) { case 'dog': console.log( 'Wang!' ) break case 'cat': console.log( 'Miao!' ) break case 'bird': console.log( 'Jiu!' ) break } //3.而Map针对性最强,而且最简洁、最易于维护。 const logMap = { dog: () => console.log( 'Wang!' ), cat: () => console.log( 'Miao!' ), bird: () => console.log( 'Jiu!' ), }
logMap[ animalType ]()
3、解耦可视化库和Vue/Vuex:
class Counter { // # state /** @type {number} */ count = 0 // # getters get countText() { return `Count is: ${ this.count }` } // # mutations /** @param {number} count*/ SET_COUNT = count => { this.count = count } // # actions /** @param {number} count*/ logCount = ( count ) => { this.SET_COUNT( count ) console.log( this.countText ) } }
“使用getters和mutations”。好比定义一个模块的:
operationGetters.js
, 里面提供各类用来获取与操做有关的常量和方法。
export const OPERATION_TYPE_A = 0 export const OPERATION_TYPE_B = 1 export const OPERATION_TITLE_MAP = { [ OPERATION_TYPE_A ]: 'Title A', [ OPERATION_TYPE_B ]: 'Title B', } export const getOperationTitleByType = type => OPERATION_TITLE_MAP[ type ]
定义mutations
则是定义一个提供相关各类变动数据方法的文件。在维护代码的时候,查找变动方法名便可直接找到更改数据的出处。
export const SET_OPERATION_TITLE = ( operation, title ) => { operation.title = title }
-end-