由于此次项目重构是由vue3和tsx进行的,所以借此机会也算是对vue3和ts有了更深入的理解,接下来就结合开发重构的过程着重介绍下TS
开发重构的过程:
-
准备工作:
- 接口汇总,参数类型总结
- 页面结构分析
- 业务逻辑梳理
- 代码梳理
-
开发过程中:
- 根据业务对原代码逻辑进行copy并重构
- 对不合理的结构进行分析重写
- 对遗漏的接口字段和类型等进行补充和完善
-
开发完成后以及bug修复阶段:
- 根据测试所提问题,继续优化原有页面以及代码逻辑
- 汇总遗漏项,后续时间进行优化
TS数据类型:
基本类型:string、number、boolean、symbol、bigint、null、undefined
引用类型:array、 Tuple(元组)、 object(包含Object和{})、function
特殊类型:any、unknow、void、nerver、Enum(枚举)
其他类型:类型推理、字面量类型、交叉类型
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定义
-
关于枚举类型:
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
开发重构的过程:
-
准备工作:
- 接口汇总,参数类型总结
- 页面结构分析
- 业务逻辑梳理
- 代码梳理
-
开发过程中:
- 根据业务对原代码逻辑进行copy并重构
- 对不合理的结构进行分析重写
- 对遗漏的接口字段和类型等进行补充和完善
-
开发完成后以及bug修复阶段:
- 根据测试所提问题,继续优化原有页面以及代码逻辑
- 汇总遗漏项,后续时间进行优化
TS数据类型:
基本类型:string、number、boolean、symbol、bigint、null、undefined
引用类型:array、 Tuple(元组)、 object(包含Object和{})、function
特殊类型:any、unknow、void、nerver、Enum(枚举)
其他类型:类型推理、字面量类型、交叉类型
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定义
-
关于枚举类型:
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
}
暂时就先总结这么多把,后续在补充