ts自动编译声明文件_拥抱 TS:细数选择 TS 的 N 种理由

作者 | 马靖

a79d37a7a9da95194edb68182774565c.png

day day up, bye bye bug

最近在做一个新项目,技术大佬告知前端要用 TS 。前端小白的我内心疑惑“弱类型语言它不香嘛,为什么选择 TS ?” 为了紧随大佬的流星大步,拥抱变化。带着这个疑惑我积(被)极(破)主(营)动(业)点开了谷歌,开始了地毯式的搜索。

1、TS 的前世今生

1.1 背景故事

2010 年微软公司的一个深夜,拥有黑眼圈的程序员们加班改 bug ,其中一个资深程序员抱怨“这声明的变量不写类型注释,还偷偷改数据类型,写的人也太不靠谱,这维护难搞哦”。正巧被路过的老板听见,第二天微软决定以该程序员为首,成立一个紧急小组开发一门新语言TypeScript,需求是提升大型 JS 项目的可靠性和可维护性。TS 从 2010 年开始研发后一直作为微软的内部项目使用,直到 2012 年,发布了第一个公开版本【 TypeScript 0.8 版 】后,受到前端程序员的激烈推崇点赞,纷纷学习使用。自此 TS 就开始了漫漫迭代之路,时至今日仍然大受欢迎。

1.2 TS 是什么

这个故事告诉我们 TS 存在的目的,是为了提升大型 JS 项目的可靠性和可维护性。那 TS 到底是什么?官方定义来了 TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source. 翻译过来:TypeScript 是 JavaScript 的一个超集,可以编译为纯 JavaScript ,在任何浏览器、集群(服务器)、操作系统上面都可以运行,而且还开源。一张图来了解它的大小。 

d467f3aa59dc73e0ecbbf55315dbfe92.png前端程序员:开发工具用 VScode;包管理用 npm;代码用 TS;社区用 GitHub。一家人就是要整整齐齐(浏览器就算了)。我们可以将 TypeScript 看作是 JavaScript 之上的一个外壳,拥有类型的 JavaScript ;TS = Type + Javascript。看到这里不禁有疑惑,它到底做了什么能成为 JS 超集,既然可编译为 JS 又是怎么提升大型 JS 项目可靠性和可维护性的呢?

1.3 TS 做了什么

  • 扩展 JS 数据类型

TS 中数据类型:boolean 类型、 number 类型、 string 类型、 Object 类、 function 类、 array 类型、 undefined、 null、 Symbol、 tuple 类型(元组类型)、 enum 类型(枚举类型)、 any 类型(任意类型)、 void 类型(没有任何类型)、 never 类型(永不存在的值的类型) TS 还提供了 as 类型断言, 强制类型转换。如果这些还不能表达出你想要的数据类型,想要组合型结构,为难我 TS ?它来了,它来了,它带着接口走来了。

  • 接口

在面向对象编程中,接口是一种规范的定义,它定义行为和动作的规范。TS 的核心原则之一是对值所具有的结构进行类型检查。它有时被称做“鸭式辨型法”或“结构性子类型化”。在 TS 里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。其实在程序设计里面,接口起到一定的限制和规范作用。接口定义对象里的属性和方法所遵守的规范。如果非要形象贴近生活一点的话,那接口就像是充电口,你是什么类型的充电口,就必须要用这个类型的充电器。你定义什么类型的接口,那你必须使用相同类型的数据。TS 的接口增加了更灵活的接口类型,包括属性,函数,索引和类等。TS 中的接口不仅可以约束,相同接口还可以合并同”名“项。了解到的和常用的接口如下:1. 属性类接口,对属性值的类型定义;2. 参数约束接口,规定调用方法的传参类型,避免出现数据类型不一致导致 JS 直接卡死在浏览器的语法错误;3. 参数修饰,可选类型、必选类型和限制接口中的参数是只读类型等;4. 泛型接口,增强了接口的可复用性;5. 函数接口,规定函数参数值类型以及返回值类型,避免出现空返回值导致中止程序的现象;6. 索引签名,可以添加不确定参数名称的属性;7. 类接口,对类的约束,和抽象类有点像;8. 接口扩展,如果你声明了两个接口名一样的接口,那么 TS 会对该接口进行合并操作;9. 使用 type 别名 可提取自定义联合类型;10. 接口做闭包,主要是混合类型,当一个函数有自己的属性和方法;

  • 提供类型系统、类型推论和静态检查

如果是在支持 TS 的 IDE 中( VS Code、WebStorm 等),则不需等到编译,编码时 IDE 就可以非常明显在 localCompare 位置提示出错误信息。非空判断 开发中有时会直接引用某个对象的属性,但有时候该属性的数据格式有可能为空,这种场景在前端处理后端接口返回值时经常出现。有时候数据层级可能非常深,如果在某一级缺少了非空判断逻辑,意味着埋下了一个不知道什么时候就会引爆的炸弹。而 TS 会对属性进行非空判断。想举个栗子证实?在声明变量的时候一旦指定变量的数据类型,后续使用到该变量的时候 TS 会进行静态数据类型分析检查,即使编写的代码即使没有被执行到,依旧进行检查。如果发现类型不匹配,在编译阶段(解释执行也一样,可以在运行前)就会直接报红报错,但只是报红并不影响它编译为 JS ,也就是说就算是有静态类型检查报错的文件,编译之后代码仍可运行。fe4bd0c340f1c9a2c0a0515e8508f18f.png

报错: Subsequent property declarations must have the same type. Property 'x' must be of type 'number', but here has type 'string'.

觉得太正经,就不想中规中矩?如果使用变量的时候没有指定数据类型,后续使用时是不是就逃过静态类型检查了呢?答案是 No ,在 TS 里,没有明确指出类型的地方,类型推论会帮助提供类型。如果是声明式,类型推论是发生在初始化变量和成员,设置默认参数值和决定函数返回值时进行的;如果没有声明,比如参数,TS 类型推论也可能按照相反的方向进行,按上下文归类,上下文归类会与表达式的类型与所处的位置关联起来,进行类型推断。别想了,你是逃不掉强检查的~ 

b5e800c17826fc44a3ab62946e8b2021.png优点:1,编译期出现不可靠代码立即报红提示,降低纯 JS 开发风险;2,类型即为最好的文档注释,人与机器双懂,降低多人开发的沟通成本,岂不三全其美。

  • 泛型

最初了解到泛型,是在大学时期学习 C# 时,老师介绍:“允许延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。泛型允许编写一个可以与任何数据类型一起工作的类或方法。可以通过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。编译器无答复,运行期才会根据需要生成。“ 在软件工程中,我们在创建一致的定义良好的 API ,同时也要考虑重用性。让组件不仅能够支持当前的数据类型,还能支持未来的数据类型。初闻不知曲中意,再听已是曲终人。当初不听老师言,如今主动去钻研!应景!其实在 C# 和 Java 强语言中,可使用泛型来创建可重用的组件,一个组件支持多种类型的数据。以自己的数据类型来使用组件。TS 也支持泛型,泛型只用于表示数据类型而非数值。泛型会捕获传入的数据类型,并定义该类型,在后续使用到泛型的地方,数据类型需要使用已经定义的泛型。泛型主要是解决类、接口、方法的复用性以及支持不定类型的数据。如下代码。function identity(arg: T): T { return arg; //如果你传入的 arg 参数为 number 类型,那么 T 就为 number }

  • IDE 智能提示

TS 完美解决了 IDE/编辑器 无法智能提示的痛点,敲代码的时候不用记太多属性,类型之类的内容。TS 会自动提示属性和类型等内容。来,看图 

d52f3d24baadd05877b6af1787d60d86.png

  • 面向对象编程增强

TS 新增访问权限控制:public:共有,类的成员属性/方法默认都是 public,没有访问限制;private:私有,无法在该类声明的外部访问其成员(如无法通过 this.xxx 访问私有成员);protected:与 private 类似,但在派生类中也可以访问受保护成员。

TS 还引入了类,声明合并、模块、模块解析、支持 TSX 等等。自己发现了解吧。手动放入 TS 官网

2、TS 与 JS 的爱恨交织

通过上面简要介绍,我们知道 TS 作为 JS 的语法糖,TS 将 JS 更加具体化类型化,在编译过程中对数据类型和代码设计更加规范也更有层次感。TS 支持 ES 标准,扩展 JS 语法,TS 原则之一永远和 ES 规范保持一致。TS 在编译时作为静态类型检查的弱类型语言,但编译后运行时是动态类型的弱语言 ,只在编译时强检查,符合 TS 设计原则,“不给编译产物增加运行时开销”。

  • 爱与恨

既然 TS 编译后依然是 JS ,那为什么前端程序员不喜欢老东家 JS 呢?聊聊我的拙见。

首先,要从 JS 的设计初衷来说。JS 定义时作为一门动态类型的弱类型语言,没有固定的数据类型,使用非常灵活。小插曲,记忆深处有次知识分享前端大佬骚操作猛如虎,后端小哥看完震惊 “原来写代码还可以这么随意,跟玩的一样”。动态类型的弱类型语言没有固定的数据结构,随时可更改数据类型,确实很灵活,正所谓动态类型一时爽,代码重构火葬场。灵活的语言有一个弊端就是没有固定数据类型,你定义什么我就执行什么,这就导致多人开发时乱赋值的现象。TS 设计原则之一是“实现一种可组合、易推理的( easy to reason about )语言”。提供类型化 + 静态类型检查 + 类型推断,来静态识别出那些可能会出错的代码,符合 TS 设计原则,“在编码阶段就扼制不安全代码的产生”。

其次,JS 的设计只有 10 天时间,最初只是一个辅助 Java 的脚本语言,小打小闹的 JS 没想成大气候,奈何太受欢迎一不小心成了名,缺少一些构建大型应用的特性,比如接口、结构化、类等等。JS 有苦说不出,没关系,TS 哥哥来帮忙。TS 提供接口,泛型等一切为大型 JS 项目所需要的东西。

  • 交织

介绍这么多,TS 弥补 JS 不足,那 TS 与 JS 在开发之外的层面,是不是只有首字母的不同呢?

  • 语言规范

JS 和 TS 都是 ECMAScript(即 ES 规范)的具体实现。TS 的设计原则之一“永远和 ES 规范保持一致“。也就是 JS 的新规范新特性,都可在 TS 中直接书写。在语言规范层面,JS 与 TS 确实只是首字母的不同。

  • 运行环境

浏览器引擎和 Node.js 都能够直接运行 JS,但无法直接运行 TS。可以用它来编写面向对象的服务端或客户端程序,需要将它们编译成 JS 代码后执行了。

  • 时序执行

As we all know.浏览器只宠 JS + HTML + CSS 集团。TS 是不能直接在被浏览器识别,TS 被真正执行前,会通过编译转换生成 JS,之后才能被解释执行。TS 可编译成 JS 代码,也就是说开发中的 JS 代码,在 TS 中依然有效可用,符合 TS 的设计原则,“输出整洁、地道、可读的 JS 代码”。

  • 家境背书

JS 由 Netscape 率先推出,现在主要由各大浏览器厂商实现。而 TS,TypeScript is a trademark of Microsoft Corporation,目前由微软进行设计和维护。

  • 重构维护

长期迭代维护的项目开发和维护的成员会有很多,长期迭代维护的项目总会遇到可维护性逐渐降低的问题,有了强类型约束和静态检查,以及智能 IDE 的帮助下,可以降低软件腐化的速度,提升可维护性,且在重构时,强类型和静态类型检查会帮上大忙,甚至拥有类型定义,会不经意间增加重构的频率(更安全、放心)。当然了,重构还是要看具体业务,切莫为了满足个人爱好,从而给整个团队带来额外的成本。

  • 开发效率

虽然需要多写一些类型定义代码,但 TS 在 VSCode、WebStorm 等 IDE 下可以做到智能提示,智能感知 bug,同时我们项目常用的一些第三方类库框架都有 TS 类型声明,我们也可以给那些没有 TS 类型声明的稳定模块写声明文件,这在团队协作项目中可以提升整体的开发效率。

3、总结

TS 适合大规模 JS 项目( JavaScript that scales )。TS 在团队协作、可维护性、易读性、可靠性(编译期暴露问题)等方面上有着明显的优点:1. 加上了类型系统,对人好,对机器好,对维护也很好,无形中增强了代码的双层可读性;对于编译阶段来说,类型定义在编译期可揪出隐藏的 bug,健壮性强;2. 类型系统 + 静态分析检查 + 智能感知提示,书写方便,使大规模的应用代码质量更高, bug 少,维护方便,就连重构也安心;3. 给应用配置、应用状态、前后端接口及各种模块定义类型,使得整个应用由类型定义组成,可扩展,多人协作更为方便、高效和安全。

彩蛋:题目有彩蛋,你是否发现

全文完


以下文章您可能也会感兴趣:

  • WePY 2.0 新特性

  • SSL证书的自动化管理

  • 了解一下第三方登录

  • 分布式 ID 生成策略

  • 单元测试的实践之路

  • 可线性化检查:与 NP 完全问题做斗争

  • Java 类型系统从入门到放弃

  • Webpack 快速上手(下)

  • Webpack 快速上手(中)

  • Webpack 快速上手(上)

我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 rd-hr@xingren.com 。

699ed08be298b486bf100adde7168a7c.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/472931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java分治法求数列的最大子段和_Java十大经典排序算法动画解析和 代码实现

排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序。内部排序是数据记录在内存中进行排序。而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:…

LeetCode 1753. 移除石子的最大得分(优先队列)

文章目录1. 题目2. 解题2.1 优先队列2.2 脑筋急转弯1. 题目 你正在玩一个单人游戏,面前放置着大小分别为 a​​​​​​、b 和 c​​​​​​ 的 三堆 石子。 每回合你都要从两个 不同的非空堆 中取出一颗石子,并在得分上加 1 分。 当存在 两个或更多 …

基于Spring框架的Shiro配置

http://kdboy.iteye.com/blog/1103794 一、在web.xml中添加shiro过滤器 Xml代码 <!-- Shiro filter--> <filter> <filter-name>shiroFilter</filter-name> <filter-class> org.springframework.web.filter.Delegating…

dat文本导入mysql_mysql学习笔记(九) 增删改查的优化

一、大批量插入数据当使用load命令导入数据的时候&#xff0c;可以适当的提高导入的速度。对于myisam存储引擎的表可以通过下述方法快速的导入大量的数据。Alter table tablename disable keys;Loading dateAlter table tabename enable keys;其中disable keys和enable keys用来…

asp.net接受表单验证格式后再提交数据_如何解析 el-form-renderer 表单渲染器1.14.0...

DEEPEXI 大前端常人道&#xff0c;一入开发深似海&#xff0c;技术学习无止境。在新技术层出不穷的前端开发领域&#xff0c;有一群身怀绝技的开发&#xff0c;他们在钻研前沿技术的同时&#xff0c;也不忘分享他们的成果&#xff0c;回馈社区。下面&#xff0c;就由小水滴带大…

LeetCode 1751. 最多可以参加的会议数目 II(DP + 二分查找)

文章目录1. 题目2. 解题1. 题目 给你一个 events 数组&#xff0c;其中 events[i] [startDayi, endDayi, valuei] &#xff0c;表示第 i 个会议在 startDayi 天开始&#xff0c;第 endDayi 天结束&#xff0c;如果你参加这个会议&#xff0c;你能得到价值 valuei 。 同时给你…

LeetCode 992. K 个不同整数的子数组(双指针)

文章目录1. 题目2. 解题1. 题目 给定一个正整数数组 A&#xff0c;如果 A 的某个子数组中不同整数的个数恰好为 K&#xff0c;则称 A 的这个连续、不一定独立的子数组为好子数组。 &#xff08;例如&#xff0c;[1,2,3,1,2] 中有 3 个不同的整数&#xff1a;1&#xff0c;2&a…

压缩可以卸载吗_番禺街坊注意!微信发送高清大文件不压缩,网友:QQ可以卸载了?...

刚上新了表情包的微信又双叒叕出新功能了这次的功能有点实用昨天&#xff0c;腾讯微信团队宣布微信已支持向朋友发送高清视频和图片且不会被压缩微信用户点击对话框右下角的号右滑点击文件在上方选择手机相册就能选择用户想要发送的视频和图片了目前通过「文件」方式发送的内容…

LeetCode 1755. 最接近目标值的子序列和(状态枚举 + 双指针)

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums 和一个目标值 goal 。 你需要从 nums 中选出一个子序列&#xff0c;使子序列元素总和最接近 goal 。 也就是说&#xff0c;如果子序列元素和为 sum &#xff0c;你需要 最小化绝对差 abs(sum - goal) 。 返回 abs(sum …

路由器距离向量算法计算举例_路由器基本原理是什么 路由器基本发展情况介绍【图文】...

PLC路由器原理和ARR路由器基本原理要实现网络中通信节点彼此之间的通信&#xff0c;首先必须给每个节点分配一个唯一的IP地址。路由器应该至少有两个网络端口&#xff0c;分别连接LAN或者WAN子网上&#xff0c;每个端口必须具有一个唯一的IP地址&#xff0c;并且要求与所连接IP…

LintCode MySQL 1918. 第二高的球员的身高

文章目录1. 题目2. 解题1. 题目 编写一个 SQL 语句&#xff0c;获取球员 (players) 表中第二高的身高 (height) 表定义: players (球员表) https://www.lintcode.com/problem/1918 2. 解题 if(a,b,c), a true&#xff0c;执行 b&#xff0c; 否则 c -- Write your SQL Que…

python中使用opencv_如何在Python中使用OpenCV Stitcher类?

你正确使用它,因为某些原因导致进程失败. 结果元组的第一个值是错误代码,0表示成功.这里你得到1,这意味着,根据stitching.hpp,这个过程需要更多的图像. enum Status { OK 0, ERR_NEED_MORE_IMGS 1, ERR_HOMOGRAPHY_EST_FAIL 2, ERR_CAMERA_PARAMS_ADJUST_FAIL 3 }; ERR_NEE…

《高可用MySQL》2 – 单机版MySQL主从配置

这里搭建的主从是最简单的单一主从复制&#xff08;即一个Master和一个slave&#xff0c;没有任何的热机备份和多slave&#xff09;&#xff0c;该主从结构的基本拓扑图如下所示&#xff1a; 建立基本的主从复制可以总结为以下三个基本步骤&#xff1a; 配置master服务器配置sl…

LintCode MySQL 1936. 张三的故事 III

文章目录1. 题目2. 解题1. 题目 记者调查发现&#xff0c;张三所在学校还有一金牌教师&#xff0c;其所带的学生毕业后人均知名学府。 记者对该老师所教的学生的情况产生了好奇。 students 表中记录了学生的姓名以及班级 (class_id)&#xff0c;classes 表中记录了班级的名称以…

语言4位bcd码怎么加加_S7300400如何使用SCL语言调用SFC1(READ_CLK)读取日期和时间?...

系统功能 SFC1 用于读取 CPU 的系统时钟。系统时钟存储在数据类型为DATE_AND_TIME的变量里。通过指针访问系统时钟的单个组成元素。数据类型DATE_AND_TIME所包含的关于年、月、日、时等信息是以 BCD 码的格式存储在 8 个字节里。该数据类型显示的范围是&#xff1a;DT#1990-1-1…

LintCode MySQL 1932/1933. 挂科最多的同学 I / II

文章目录1. 题目2. 解题1. 题目 exams 表中存放着同学们的考试记录 请用 SQL 语句&#xff0c;找到挂科数最多的同学所对应的 student_id https://www.lintcode.com/problem/1932 2. 解题 -- Write your SQL Query here -- -- example: SELECT * FROM XX_TABLE WHERE XXX…

python 画三角函数_python,将三角函数绘制成二维数组

看起来a, b, c是常量&#xff0c;z是a和{}之间的np.linspace。在a 1 b 2 c 3 def triangle (z, a a, b b, c c): y np.zeros(z.shape) y[z < a] 0 y[z > c] 0 first_half np.logical_and(a < z, z < b) y[first_half] (z[first_half]-a) / (b-a) second…

LeetCode 1758. 生成交替二进制字符串的最少操作数(DP)

文章目录1. 题目2. 解题1. 题目 给你一个仅由字符 ‘0’ 和 ‘1’ 组成的字符串 s 。 一步操作中&#xff0c;你可以将任一 ‘0’ 变成 ‘1’ &#xff0c;或者将 ‘1’ 变成 ‘0’ 。 交替字符串 定义为&#xff1a;如果字符串中不存在相邻两个字符相等的情况&#xff0c;那…

python内置的集成开发工具是什么_python内置的集成开发工具是什么_后端开发

go语言之goroute协程_后端开发 协程&#xff08;coroutine&#xff09;是Go语言中的轻量级线程实现&#xff0c;由Go运行时&#xff08;runtime&#xff09;管理。下面就来由go入门教程栏目介绍一下go语言中的goroute协程。python内置的集成开发工具是什么 Python自带的集成开发…

SQL Server 2008R2数据库文件导入到SQL Server 2008数据库中

最近&#xff0c;电脑重装系统之后&#xff0c;安装了SQL Server 2008。附加数据库文件的时候&#xff0c;发现无法附加&#xff0c;提示版本不对。想起来&#xff0c;原来的数据库版本是SQL Server 2008R2。低版本的数据库管理工具无法兼容高版本的数据库文件&#xff0c;所以…