当领导问我为什么选择typescript?
“换做是你,被领导问到这类问题,你会怎么说?”,给你一首歌的时间想一想~
话不多说,进入正题!被问到这类问题,领导无非是想了解你行动背后的动机,即
- 为什么要引入typescript,它解决了什么问题?
- 目前业务中存在哪些痛点?
- 预估成本和风险收益计算?
围绕上面问题,接下来站在业务角度一起聊聊
背景
在业务部门做技术,一切都是以驱动业务发展为首要前提。
在当时,我们存在以下几类问题:
- 为解决业务常见工单、研发痛点问题
- 为减少运行时JavaScript常见的8种错误
- 尝试提升代码质量、可维护性
第一点
由于业务产品面向群体为B端
企业,内部有一套工单系统用于客户反馈产品使用过程中产生的问题,通过统计,前端类型工单存在一部分问题是由于代码运行时结果不及预期,而在开发环境、测试环境以及预发布环境测试都没有出现,它们诸如:
data.x
为undefined
,导致页面上显示undefined
字样,对用户体验极其不好data.a.b
运行时异常,a
可能存在值为null | undefined
,导致页面异常- 后端改了某个接口某个字段的数据类型,没有同步前端修改、因场景较多改漏了
- 前端同学由于粗心,字段名改错了,测试没有覆盖到该场景
- 修改某个逻辑的时候,由于场景比较复杂,一个字段存在多种数据类型的情况,开发者不能一眼穷举出所有数据类型的情况,于是用数组的方法操作了对象,产生工单问题
而关于研发痛点
问题,它们是:
- 在前端联调过程中,多次因为类型不确定导致对接过程中出现参数错误,对研发效能有一定影响
- 一个函数根据场景不同接受不同的对象属性,在维护过程中,维护者无法很快知道当前某个场景需要的对象含有什么属性,并且不知道属性一定存在与否,造成逻辑层的风险不可控以及不低维护成本
- 重构逻辑时误删代码、修改变量、方法、文件,改漏或者出错,导致工单问题
第二点
rollbar
监控平台于 2018 年统计了前端项目中 Top10 的错误类型,其中有 7
个是类型错误(TypeError
):
Cannot read property 'xxx' on undefined:
无法在 undefined 上读取 xxx 属性,通常出现在a.b.c
的情况。’undefined’ is not an object:
undefined 不是对象null is not an object:
null 不是对象undefined' is not a function:
undefined 不是函数,通常出现在a.b.c()
的情况Object doesn't support property or method:
调用了一个不存在的属性或方法Cannot read property ‘length' of undefined:
无法读取 'length' 属性,本来期望一个数组,但是变量的实际类型却不是数组Uncaught TypeError: Cannot set property ‘value’ of undefined:
无法给 undefined 设置属性,通常是对象被篡改为其他类型
除了 7 个 TypeError,还有一个 ReferenceError: 'xxx' is not defined:xxx
没有定义。
我们无法完全避免这些问题产生,尽可能在编译阶段提前暴露,减少运行时错误。
第三点
团队成员的能力是存在梯度的,梯度的分层根据能力和经验来界定,大致分为:0-1年初级开发和实习生、1-3年初中级开发和3-5年中高级开发,面对前两级的成员的代码质量相对低下,诸如规范问题、性能问题以及异常保护问题较为常见,统一代码风格和质量只靠PR环节
和code review
显得力不从心,所以我们需要工具来帮助解决此类问题。
行业解决方案
面对前面提到的业务背景和业务痛点,行业给出了主流的解决方案,主要两种主流静态类型检查系统:flow
和 TypeScript
:
选择typescript的原因
解决问题能力:
- TS能够较好的解决我们前面提到类型错误引发的工单问题,在编译阶段提前暴露常见JS类型错误问题,提升运行时代码质量
- 能够借助IDE智能提示,友好编写、组织代码结构
- 对重构友好,提升重构质量和效率
- 生态:npm社区活跃、IDE工具支持度、框架(react、angular、vue3)支持完善,声明文件不断丰富。
- 新特性支持:TS遵循标准,而非自己定制标准。可以支持ES789相关新特性。
- 易调试:错误定位比较准确,能够准确告诉开发者哪里流入一个不兼容的类型,类型的哪一部分不兼容,可以快速定位问题源头。
- 趋势:一线大厂(腾讯、字节)反馈在新项目中更倾向于使用TS。同时vue社区对TS的热度极高,比如vue3完全使用TS重写。
typescript与js对比
TypeScript具有类型系统,且是JavaScript的超集。 它可以编译成普通的JavaScript代码。
对比
从运行时看,红色部分代码是额外的,但是从代码质量和可维护性看,这部分代码是必不可少的。否则,必须通过JSDoc
(js注释)的方式来声明清楚接口类型,而TS仅仅是一种更优雅方案的选择。
JavaScript代码风格
上面代码,维护者无法从直观上想象这个对象里面有什么属性,需要找到指定场景调试才能看到具体数据。
TypeScript代码风格
成本预估
业务中,动作背后的成本是不容忽视的,需要关注一个重要指标:ROI(投入产出比)
成本:
- 我们从上面对比可以看到,实际开发中TS需要编写额外的数据接口模型(
interface
)、类型声明(type
)等 - 目前主流的第三方库已经有提供TS版本,可以直接使用,如果是不支持第三方js库,我们可以考虑按需进行TS声明,而第三方UI库声明成本较小,比如
iview
: - 统计组员熟悉程度,评估上手成本,针对性做培训
风险收益
风险
重构与优化是会产生风险
与收益
的博弈,当然啦,我们是需要保证天平倾向于后者,这个动作背后如何去评估和控制风险呢?
- 单元测试,针对核心的逻辑进行单测,在typescript中这点不难,但是需要划分维度进行,这里面也存在成本与收益的权衡
- 在测试环境中进行灰度,重构在正常情况下不能够影响正常的系统迭代,即不影响其他功能在测试环境中进行测试
- 线上环境中进行灰度,针对用户群体灰度,可以按照客户所属业务模块划分、也可以通过客户id进行分批开放
收益
投入后必然要看到收益,而重构收益是一个无法非常直观看出来的概念,我们借助一些指标进行量化,如:
- 客户反馈工单数,匹配上面提到的
类型错误
占比存在多少 code review
反馈结果PR
打回次数中,针对数据类型
错误占比
总之,将运行时类型错误前置暴露,从而有效提升代码质量、增强可维护性。
总结
全文回答了为什么会选择typescript
,通过逻辑链思维
,介绍了动作背后的原因(为什么)以及行动计划(怎么做)。
介绍了开发中常见的类型错误,行业中又是怎么解决此类问题,最后讲到业务中必然要考虑的成本、风险和收益的权衡。
转载自:https://juejin.cn/post/7283873796977000500