TypeScript:前端世界的“甜蜜烦恼”——究竟该不该用?

2024-03-04 18:52

本文主要是介绍TypeScript:前端世界的“甜蜜烦恼”——究竟该不该用?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • TypeScript:前端世界的“甜蜜烦恼”——究竟该不该用?
    • 引子:JavaScript,爱你不容易
    • 第一层考量:类型系统,你的福音还是束缚?
      • 1.1 类型系统的甜头
        • (1)静态类型检查
        • (2)智能提示与自动补全
        • (3)更好的文档性
      • 1.2 说的好听点类型系统的挑战,其实就是缺点
    • 第二层考量:从项目与团队角度出发
      • 2.1 大型项目与团队协作
      • 2.2 小型项目与个人开发
    • 结语:所有的所谓的静态类型将来会被AI代替

TypeScript:前端世界的“甜蜜烦恼”——究竟该不该用?

引子:JavaScript,爱你不容易

在前端的广阔天地里,JavaScript(简称JS)无疑是最闪耀的那颗星。它像一位充满魅力但又时不时捉摸不透的艺术家,让我们既爱且恨。尽管其灵活、动态的特性赋予我们无限可能,但随着项目规模的增长和团队协作的需求增强,JS原始形态下的类型缺失、易出错等痛点也愈发凸显。

这时,我们的救星TypeScript(简称TS)应运而生,它的口号是:“JavaScript that scales.” 那么,对于前端开发者来说,究竟是否应该拥抱TypeScript呢?让我们一起探讨这个“甜蜜的烦恼”。

第一层考量:类型系统,你的福音还是束缚?

1.1 类型系统的甜头

(1)静态类型检查

TypeScript最大的特点就是引入了静态类型系统,能在编译阶段就发现潜在的类型错误,极大程度地减少了运行时错误的可能性。在复杂应用上线后,难免碰到undefindnull之类的问题,TypeScript可以降低这种问题的发生,但是代价是多些代码,我们在写js代码的时候多做合规的过滤。

// TypeScript
let name: string = 'Alice';
name = 123; // 编译阶段就会报错,不能将数字赋值给字符串// JavaScript
let name = 'Alice';
name = 123; // 运行时不会报错,但在后续使用中可能会引发问题

上面的是不是很简单?然后实际工作中:

declare module 'estree-walker' {export function walk<T>(root: T,options: {enter?: (node: T, parent: T | undefined) => anyleave?: (node: T, parent: T | undefined) => anyexit?: (node: T) => any} & ThisType<{ skip: () => void }>,)
}
export type TypeEqual<Target, Value> =(<T>() => T extends Target ? 1 : 2) extends <T>() => T extends Value ? 1 : 2? true: false
export function describe(_name: string, _fn: () => void): void
export function expectType<T>(value: T): void
export function expectError<T>(value: T): void
export function expectAssignable<T, T2 extends T = T>(value: T2): void

受到打击了没?看得懂不?关键问题是这不是很复杂的。
绝大多数情况下,.d.ts文件依然需要手动编写,无法自动生成。此外,在一些情况下即使有自动工具可以生成类型信息,例如通过编译JavaScript代码生成.d.ts文件,它们可能无法准确反映作者的意图或者覆盖所有的边缘情况,因此可能仍需人工调整和维护。

(2)智能提示与自动补全

智能提示与自动补全是IDE(集成开发环境)结合TypeScript编译器提供的功能。在编写TypeScript代码时,IDE之所以能够提供智能提示和自动补全,主要是基于以下几点:

  1. 类型系统
    TypeScript的核心特性是静态类型系统,它允许开发者为变量、函数参数和返回值等定义明确的类型。编译器在解析代码时会根据这些类型信息建立一个内部的符号表(或称类型图),这个表包含了项目中所有已知类型的详细信息。

  2. 类型推断
    除了显式声明类型外,TypeScript编译器还具有强大的类型推断能力。即使没有明确指定类型,编译器也能通过上下文和赋值方式来推测出变量可能的类型。

  3. 语法分析
    IDE监听并实时分析你正在编辑的源代码文件,通过调用TypeScript语言服务API获取到编译器对当前代码段的理解,包括但不限于:变量作用域、类结构、接口定义以及模块导入导出关系等。

  4. 插件/扩展支持
    大多数现代IDE如Visual Studio Code、WebStorm等都提供了针对TypeScript的插件或内置支持,这些插件可以与TypeScript编译器紧密集成,利用编译器生成的类型信息提供实时的智能提示和自动补全。

  5. 缓存与索引
    IDE通常会对项目中的.ts文件进行索引和缓存,以便快速检索和响应用户输入,当用户开始键入时,IDE可以根据当前上下文快速查询相关类型信息,并展示相应的建议。

实际上,智能提示与自动补全功能并非仅仅是IDE(集成开发环境)实现的结果,它更是TypeScript语言设计本身的特性所支持的。TypeScript通过引入静态类型系统和丰富的类型注解,在编译器层面就能够推断出代码中变量、函数以及其他实体的类型信息。这些类型信息为IDE提供了强大的上下文,使得IDE能够准确地进行智能提示和自动补全。

IDE如Visual Studio Code(VS Code)、WebStorm等确实是在其内部集成了对TypeScript语言特性的支持,并且会不断优化以提供更好的开发者体验。微软作为TypeScript的创建者,自然会在自家的开发工具中优先并深度整合TypeScript的支持,但同时,开源社区以及众多第三方IDE也都在积极跟进TypeScript的发展,提供相应的插件或内置支持。

将智能提示与自动补全完全归结为“微软给钱让IDE去实现”或者“向资本妥协的产物”并不准确。

(3)更好的文档性

类型声明在TypeScript中确实起到了增强代码可读性和自注释性的作用,特别是对于大型项目和团队协作来说,明确的类型信息能够显著减少理解成本和潜在的错误。然而,当类型声明变得极其复杂时,它们可能反而会增加阅读难度,特别是对于那些初学者或不熟悉特定类型构造的人来说。

复杂的类型表达式,比如高级的联合类型、映射类型、条件类型、泛型约束等,在提供了强大功能的同时,也要求开发者具备一定的抽象思维能力和TypeScript类型系统的深入理解。过度复杂的类型声明可能会成为一种“技术债”,如果设计得不够直观易懂,反而会导致维护困难和团队成员间的沟通成本上升。

1.2 说的好听点类型系统的挑战,其实就是缺点

虽然TypeScript(TS)为前端开发带来了很多好处,如静态类型检查、更好的可维护性和代码提示等,但正如你所提,对于特定场景和开发者来说,它的缺点可能会被看作是大于优点的。以下是一些突出的TypeScript缺点:

  1. 学习成本

    • TypeScript引入了额外的概念和语法,比如接口(Interfaces)、泛型(Generics)、类(Classes)、枚举(Enums)等,这需要前端工程师投入时间去学习和适应,尤其对那些习惯于JavaScript动态特性的开发者来说,可能存在一定的学习曲线。
  2. 开发初期成本增加

    • 在项目开始阶段,编写类型定义会增加开发工作量,尤其是对于小型项目或快速原型开发,可能觉得额外的类型注解降低了迭代速度。
  3. 代码量增多

    • 类型注解使得源代码文件在直观上显得更长,尤其是在大型项目中,因为每个变量、函数和对象都需要明确指定类型。
  4. 编译时性能损耗

    • TypeScript需要通过编译器将源码转换成JavaScript,这个过程增加了编译时间,特别是对于复杂项目,可能导致构建速度变慢。
  5. 集成与兼容性问题

    • 尽管大多数流行的库和框架都提供了TypeScript支持,但并非所有第三方库都能完美地提供类型定义文件,或者需要手动进行类型封装,这在一定程度上影响了开发效率和体验。
  6. 灵活性降低

    • 静态类型的严格约束可能限制了一些JavaScript灵活编程的特性,对于追求快速迭代、尝试新想法的团队来说,过于严格的类型系统可能会被视为一种束缚。
  7. 错误处理与调试

    • 虽然类型检查能在很大程度上避免运行时错误,但错误消息有时可能较为复杂难懂,特别是在类型推断出错的情况下,开发者可能需要花费更多时间理解并修复类型错误。
  8. IDE依赖度提高

    • TypeScript的优势很大程度上取决于开发环境的支持,如果使用不支持TypeScript智能提示和自动补全功能的IDE,开发效率可能不如预期。
  9. 类型声明文件(.d.ts)的手动维护

    • 对于使用第三方库或模块时,为了在TypeScript项目中充分利用类型检查,通常需要对应的.d.ts声明文件。虽然许多流行的开源库都包含了官方提供的类型定义,但并非所有库都能自动获取或自动生成这些类型声明。对于没有提供类型声明的库,开发者可能需要手动编写或从DefinitelyTyped等社区资源中寻找并安装合适的类型声明文件,这无疑增加了额外的工作负担。

总之,是否选择使用TypeScript要根据具体项目需求、团队技术栈和长期维护计划来综合判断。对于注重软件质量、团队协作以及有长期稳定发展需求的大型项目而言,TypeScript带来的收益往往远大于短期的成本付出。而对于小规模项目或是重视快速迭代的团队,则可能更倾向于保留JavaScript的灵活性。

第二层考量:从项目与团队角度出发

2.1 大型项目与团队协作

在大型项目或多人协作的场景下,TypeScript的优势稍微明显。通过统一的类型约束,可以保证团队成员遵循一致的编码规范,降低沟通成本,提升代码质量。前提是能看得懂.d.ts,你们还在琢么着这个类型怎么定义,怎么导出的时候,人家竞品已经发布上线了。

2.2 小型项目与个人开发

对于小型项目或者个人开发,使用TypeScript可能带来的额外负担相对较大。但如果注重长期维护性和代码质量,TypeScript仍然是一个值得考虑的选择。

结语:所有的所谓的静态类型将来会被AI代替

AI在未来编程中的潜在作用,确实,随着人工智能技术的发展,AI有可能在编译阶段更好地辅助甚至替代部分人工对类型错误、未定义变量等问题的检查和修复。这种设想中,AI可以更智能地理解代码意图,并自动调整类型以符合预期的行为。

这篇关于TypeScript:前端世界的“甜蜜烦恼”——究竟该不该用?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/774129

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

CSS @media print 使用详解

《CSS@mediaprint使用详解》:本文主要介绍了CSS中的打印媒体查询@mediaprint包括基本语法、常见使用场景和代码示例,如隐藏非必要元素、调整字体和颜色、处理链接的URL显示、分页控制、调整边距和背景等,还提供了测试方法和关键注意事项,并分享了进阶技巧,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分