重构项目中ts的应用

311 阅读7分钟

由于此次项目重构是由vue3和tsx进行的,所以借此机会也算是对vue3和ts有了更深入的理解,接下来就结合开发重构的过程着重介绍下TS

开发重构的过程:

  1. 准备工作:

  • 接口汇总,参数类型总结
  • 页面结构分析
  • 业务逻辑梳理
  • 代码梳理
  1. 开发过程中:

  • 根据业务对原代码逻辑进行copy并重构
  • 对不合理的结构进行分析重写
  • 对遗漏的接口字段和类型等进行补充和完善
  1. 开发完成后以及bug修复阶段:

  • 根据测试所提问题,继续优化原有页面以及代码逻辑
  • 汇总遗漏项,后续时间进行优化

TS数据类型:

基本类型:stringnumberbooleansymbolbigintnullundefined

引用类型:arrayTuple(元组)、 object(包含Object{})、function

特殊类型:anyunknowvoidnerverEnum(枚举)

其他类型:类型推理字面量类型交叉类型

ts接口类型:

在此次开发中,作为协助者,我负责的部分并不多:包括接口ts类型汇总,基础信息部分和买卖家信息部分代码和逻辑重构,其中从样式布局到逻辑编写,工作量还是比较大的,对于ts也有了比较深入的理解。

此次开发中主要运用interface接口,主要对接口的传参和返回值进行类型的约束,此时在代码编写是就会有智能的提示:在调用时把鼠标放在括号里就会提示所需要的参数和参数的类型,如果传递的类型不对也会智能提示红色波浪线,这对于代码的开发和后续的代码维护非常友好,能够非常清晰的就能看到问题所在。这也是为什么很多大型项目都要接入ts的原因,包括现在的主流框架react和vue3都完美兼容ts。

1、interface:

Interface可以直接定义ts的类型,同时他有个很大的优势就是实现ts的继承:

普通变量类型:

interface Person {

    name: string

}

interface LiPerson extends Person {

    age: number  // 关于可选属性,如果换成 age?: number, 多了个问号,此时代表age这个属性是可有可无的非必要属性

}

// 如下图,这是如果我们定义一个方法要传入LiPerson类型的参数,在我们调用时就会直接提示两个参数,而不是只有一个age,因为我们通过extends继承了Person上的name属性

函数类型:

const myFunc = (age: number, name?: string) : void => {

if (name) {

console.log(name)

} else {

console.log(age)

}

}

// 如果参数中有非必填项,则可以通过?:的形式去定义,表示此参数可有可无,不过在定义函数时必须写在参数的最后面

2、类(class):

通过对创建的类进行ts类型约束,这样通过类构建的实例就会继承这个类里面的方法和属性的ts类型。

这里通过类创建的实例就继承了原本类的ts类型

此次订单重构ts类型的定义主要是以上两种方式来完成,接口的定义用类实现,变量及接口返回值则用interface定义
  1. 关于枚举类型:

enum myType {

A,

B,

C,

D = 9,

E,

F,

}

const a = myType.A // 0

const b = myType[10] // 'E'

const e = myType.E // 10

const d = myType[9] // 'D'

// 数字枚举在默认值前面TS是默认从0开始累加,默认值后面则从默认值往后累加,没有默认值则从0累加

同时数字枚举还有(反向映射,即从成员值到成员名的映射)

字符串枚举必须有默认值,而且不能反向映射

4、泛型

const calcArray = <T,U>(name:T, age:U): {name:T, age:U} => {

const res: {name:T, age:U} = {name, age}

return res

}

const res = calcArray<string, number>('小杜杜', 7)

console.log(res) // {"name": "小杜杜", "age": 7}

// 以上函数的例子中, 在不确定需要传入的值是什么类型的时候,就可以通过泛型在函数调用的时候把传递的类型一同传递过去,在接口定义的时候也相同:

type Info<T = string> = {

name?: T

age?: T

}重构实践

最近做了个重构的项目,是由vue3和tsx进行的,所以此次参与订单详情的重构也算是对vue3和ts有了更深入的理解,接下来就结合开发重构的过程着重介绍下TS

开发重构的过程:

  1. 准备工作:

  • 接口汇总,参数类型总结
  • 页面结构分析
  • 业务逻辑梳理
  • 代码梳理
  1. 开发过程中:

  • 根据业务对原代码逻辑进行copy并重构
  • 对不合理的结构进行分析重写
  • 对遗漏的接口字段和类型等进行补充和完善
  1. 开发完成后以及bug修复阶段:

  • 根据测试所提问题,继续优化原有页面以及代码逻辑
  • 汇总遗漏项,后续时间进行优化

TS数据类型:

基本类型:stringnumberbooleansymbolbigintnullundefined

引用类型:arrayTuple(元组)、 object(包含Object{})、function

特殊类型:anyunknowvoidnerverEnum(枚举)

其他类型:类型推理字面量类型交叉类型

ts接口类型:

在此次开发中,作为协助者,我负责的部分并不多:包括接口ts类型汇总,基础信息部分和买卖家信息部分代码和逻辑重构,其中从样式布局到逻辑编写,工作量还是比较大的,对于ts也有了比较深入的理解。

此次开发中主要运用interface接口,主要对接口的传参和返回值进行类型的约束,此时在代码编写是就会有智能的提示:在调用时把鼠标放在括号里就会提示所需要的参数和参数的类型,如果传递的类型不对也会智能提示红色波浪线,这对于代码的开发和后续的代码维护非常友好,能够非常清晰的就能看到问题所在。这也是为什么很多大型项目都要接入ts的原因,包括现在的主流框架react和vue3都完美兼容ts。

1、interface:

Interface可以直接定义ts的类型,同时他有个很大的优势就是实现ts的继承:

普通变量类型:

interface Person {

    name: string

}

interface LiPerson extends Person {

    age: number  // 关于可选属性,如果换成 age?: number, 多了个问号,此时代表age这个属性是可有可无的非必要属性

}

// 如下图,这是如果我们定义一个方法要传入LiPerson类型的参数,在我们调用时就会直接提示两个参数,而不是只有一个age,因为我们通过extends继承了Person上的name属性

函数类型:

const myFunc = (age: number, name?: string) : void => {

if (name) {

console.log(name)

} else {

console.log(age)

}

}

// 如果参数中有非必填项,则可以通过?:的形式去定义,表示此参数可有可无,不过在定义函数时必须写在参数的最后面

2、类(class):

通过对创建的类进行ts类型约束,这样通过类构建的实例就会继承这个类里面的方法和属性的ts类型。

这里通过类创建的实例就继承了原本类的ts类型

此次订单重构ts类型的定义主要是以上两种方式来完成,接口的定义用类实现,变量及接口返回值则用interface定义
  1. 关于枚举类型:

enum myType {

A,

B,

C,

D = 9,

E,

F,

}

const a = myType.A // 0

const b = myType[10] // 'E'

const e = myType.E // 10

const d = myType[9] // 'D'

// 数字枚举在默认值前面TS是默认从0开始累加,默认值后面则从默认值往后累加,没有默认值则从0累加

同时数字枚举还有(反向映射,即从成员值到成员名的映射)

字符串枚举必须有默认值,而且不能反向映射

4、泛型

const calcArray = <T,U>(name:T, age:U): {name:T, age:U} => {

const res: {name:T, age:U} = {name, age}

return res

}

const res = calcArray<string, number>('小杜杜', 7)

console.log(res) // {"name": "小杜杜", "age": 7}

// 以上函数的例子中, 在不确定需要传入的值是什么类型的时候,就可以通过泛型在函数调用的时候把传递的类型一同传递过去,在接口定义的时候也相同:

type Info<T = string> = {

name?: T

age?: T

}

暂时就先总结这么多把,后续在补充