7个拒绝使用TypeScript的借口
译者按: TypeScript 学习成本不高,项目切换成本不低,不过还是值得试一试的!
为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。
自从 6 年前诞生,TypeScript 逐渐被各大型公司接受。 也许你有充足的理由说服自己不要使用它,这些都让你错失了 TypeScript。在这篇文章中,我会列举大家为何不选用 TypeScript 的一些原因,比如学习曲线、工具、开发效率、稳定性以及对标准的兼容性。
1. 学习曲线过于陡峭
首先需要强调一点:TypeScript 并不是一个完全崭新的开发语言。像 CoffeeScript 和 Reason 吸收了 Ruby 和 OCaml 的语法和语义融入到 JavaScript 语言中。TypeScript 从某种程度上说,更加保守。
它只是在 JavaScript 的基础上添加了类型系统(TypeScript 是 JavaScript 的超集),所以它的学习曲线会相对平滑。特别是相对于完全切换到不同编程语言来说。
下面是一段 TypeScript 代码:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
对比用 ES6 编写的相同功能的代码:
class Greeter {
constructor(message) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
正如 TypeScript 语言的一个设计者 Anders Hejlsberg 说到:“如果你懂得 JavaScript,那么你就已经懂得 TypeScript 了。” 稍后,我会介绍如何将现有的项目切换到 TypeScript 去。
2. JavaScript 是标准,TypeScript 不是
当 TypeScript 在 2012 年诞生的时候就有了类和模块的概念,标准 JavaScript 直到 2015 年都还没有!
今天,TypeScript 语言紧随 ECMAScript 的定义,几乎实现了Stage 3所有的提案。也就是说,当你在使用 TypeScript 的时候,你其实已经在用最新的 JavaScript。而且感谢 ES3/ES5 编译器,最终输出的.js
文件即使在旧版本的浏览器也不会出问题。
3. 破坏了 JavaScript 的动态性
如果你熟练使用脚本语言工作,你会喜欢它惊人的开发效率。你可以在代码中随时修改数据结构,而不必事先声明。这种自由度,也伴随着代价。这种动态语言有了 bug 有时候很难搞定,它不会像静态语言一样,在编译的时候有做类型的验证来保证代码的正确性。
比如下面的 JavaScript 代码:
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
通过代码我们可以判断 person 参数是一个对象,它有 firstName 和 lastName 两个属性。但是我们无法保证在运行时一定是这样。
特别是当你的项目越大,和类型相关的 bug 就越可能触发。
为了避免出现问题,我们可以加上很多运行时的验证,以及单元测试:
function greeter(person) {
if (!person || !person.firstName || !person.lastName) {
throw new Error("invalid arguments");
}
return "Hello, " + person.firstName + " " + person.lastName;
}
// Jasmine spec:
describe("greeter", function() {
it("returns greeting on valid input", function() {
expect(greeter({ firstName: "James", lastName: "Hetfield" })).toEqual(
"Hello, James Hetfield"
);
});
it("throws on invalid input", function() {
expect(() => greeter()).toThrowError("invalid arguments");
expect(() => greeter(5)).toThrowError("invalid arguments");
expect(() => greeter({ firstName: "Jason" })).toThrowError(
"invalid arguments"
);
});
});
但是,这样的实现方法很累赘,开发者需要在每个函数前面都加上这样的判断来保证正确性。换个思路,如果我们给函数的参数加上类型,这个事情不就省去了么。
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
// Jasmine spec:
describe("greeter", function() {
it("returns greeting", function() {
expect(greeter({ firstName: "James", lastName: "Hetfield" })).toEqual(
"Hello, James Hetfield"
);
});
});
上面的代码更加简洁,甚至连测试也只需要考虑代码的逻辑而不是数据的正确性。
TypeScript 有强大的类型系统来做类型推断。你并不需要像在 C# 或则 Java 中那样,显示的列出数据的类型。下面是一个例子:
let user = { firstName: "James", lastName: "Hetfield" };
console.log(greeter(user));
上面的代码可以成功编译。请注意我们并没有声明 user 是 Person 类型的。
TypeScript 编译器并不会强制你必须在所有地方都声明类型,你可以在正确性和效率上自己做一个权衡。你甚至可以在项目不同的区域自定义类型的严格程度。这样的灵活性超出了以前所有的开发语言。
4. TypeScript 火不过 5 年
没有人可以确保哪种语言、工具或者框架一定可以持续活跃,特别是在前端这一领域。一个StackOverflow 博客的作者这样写道:
在 JavaScript 框架的使用有两个明显的阶段。因为框架的流行首先有一个快速的上升期,然后当开发者接触到其它新的技术后,慢慢的平稳的下降。整个周期也就几年的时间。
你本身处于一个快速迭代的行业,而你开发的项目可以从某些特定的技术中受益。尽管 1、2 年后,你已经切换到其它技术,但是你当时学到的经验依然值得。
5. TypeScript 没有社区驱动
TypeScript 由微软在 2012 年发布,考虑到公司的形象以及其开发平台,很容易产生“只不过是给.Net 开发者打造的一个 JavaScript 开发玩具而已”的想法。特别是当时只有 Visual Studio 对 TypeScript 有足够的支持。事实上,TypeScript 的源代码最开始是发布在CodePlex上,一个微软自己的 GitHub。
不过,现已不复当年,TypeScript 身后的开发团队意识到为了让语言被广泛接受,他们需要深入前端开发社区,为开发者提供高质量的开发工具并且接受反馈不断改进。他们不仅仅是把代码公开然后默默开发,而是拥抱了一个开放式开发的方式。
在 2014 年,TypeScript 的源代码移到了GitHub托管。而且整个开发都在 GitHub 上公开透明。他们同时接受外部提交贡献,包括记录 bug,提出建议以及提交 pull request。所有的 issue 会定期更新,几天之内就会有回应。核心团队发布了语言的设计理念用来指导团队不偏离目标并积极吸收社区的建议。他们有一个保持更新的roadmap(基本上每两个月发布一次更新),并记录重大的更新。
在我写这篇文章的时候,所有主流的跨平台 IDE 或则编辑器像 Eclipse、Webstorm、Emacs、Vim、Sublime、Atom 和 VS Code 都对 TypeScript 有着很好的支持,要么是内置的,要么通过插件。为了和现有的库和框架交互,核心团队花了很多时间来创建类型定义文件。另一个值得一提的是编译器 API 的文档非常完善,可以很好地构建第三方工具。TypeScript 的开发者团队也鼓励开发者在StackOverflow上提出技术问题。
6. 切换成本过高
为了充分发挥 TypeScript 的优势,你需要花费不少时间来声明类型并修复编译错误,这会很繁琐。TypeScript 的创建者们有考虑到原有 JavaScript 项目切换的问题,提供了相应的方案。
根据官方的迁移指导,你可以直接运行 TypeScript 的编译器。编译器会抛出一些低层级的 bug,比如没有 return 语句,代码块中有永远不会执行的代码。然后,你可以将.js 文件重命名为.ts 文件,然后再处理编译结果。编译器默认的选项没有特别严格,你可以开启更加严格的验证。整个迁移有一个底线:整个过程是相当平滑的,它不会使开发中断。你可以选择慢慢将一个项目切换到 TypeScript,或则来个快速的切换(参考:3 天搞定 60 万行代码的迁移)。社区还有一个叫做TypeWiz的项目可以自动给代码添加类型信息。
7. 但是我使用的库都是基于 JavaScript
为了和现有的 JavaScript 模块无缝对接,TypeScript 支持类型声明文件。举个例子,如果你使用的库中导出了一个 camelize 的函数,你可以定义一个类型声明文件并给出如下的定义:
declare function camelize(s: string): string;
当你导入类型声明文件后,TypeScript 会正确获取函数对应的类型。
TypeScript 同时也发布了DefinitelyTyped,这个 repository 包含了所有流行的库的类型定义文件。在我写这篇文章的时间点,DefinitelyTyped 已经包含了超过 5000 个 JavaScript 包的类型定义。使用方法非常简单:
npm install --save-dev @types/jasmine
类型文件会自动被编译器包含,并且在编辑器中也会有对应的代码提示。几乎所有或则大多数你使用的包都已经有对应的类型定义文件了,要么自身有相应的类型定义文件,要么在 DefinitelyTyped 可以找到,你只需要下载安装就好。Slack 的开发团队分享了他们的经验:
考虑到代码维护,我们真的很感谢 TypeScript 强大的生态系统。我们是 React 和 Node/npm 的重度用户,第三方库也有对应的类型文件极大方便了开发。很多我们导入的库已经和 TypeScript 兼容。如果没有,那么也可以在 DefinitelyTyped 找到。比如,React 并没有自带类型定义,你可以通过
npm install @types/react
来安装,无需其他额外操作。
结论
使用静态类型检车可以帮助你消除很多 bug,对于一个基于 Node/JavaScript 的项目,TypeScript 是你最好的选择。对于一个相对小或则试验性的项目,也许没有必要。但是,一个大型的项目,TypeScript 绝对值得你尝试。它带来的好处远远大于它带来的复杂度。一些大型的公司都开始使用也是最好的证明,比如 Google、Slack、Asana、Ember 等等。希望这篇文章给你启发,让你重新燃起对 TypeScript 尝试的欲望。
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!
版权声明
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/12/26/7-bad-execuses-for-not-using-ts/
7个拒绝使用TypeScript的借口的更多相关文章
- Typescript学习笔记(四)class 类
typescript的类,与c#,java等语言的类类似.也是包含了一大部分的es6的实现.我会用最通俗的语言讲一下对coding有用的地方. class Greeter { greeting: st ...
- 学习angualr之前需要了解的typeScript知识
官网 : www.typescriptlang.org 1.编译型语言 2.强类型语言 3.真正的面向对象的语言: 有借口.有泛型.有枚举.有访问修饰符 AMD类型的面向对象的语言 npm ...
- TypeScript学习笔记(四) - 类和接口
本篇将介绍TypeScript里的类和接口. 与其他强类型语言类似,TypeScript遵循ECMAScript 2015标准,支持class类型,同时也增加支持interface类型. 一.类(cl ...
- webpack构建多页面react项目(webpack+typescript+react)
目录介绍 src:里面的每个文件夹就是一个页面,页面开发相关的组件.图片和样式文件就存放在对应的文件夹下. tpl:里面放置模板文件,当webpack打包时为html-webpack-plugin插件 ...
- TypeScript完全解读(26课时)_9.TypeScript完全解读-TS中的类
9.TypeScript完全解读-TS中的类 创建class.ts文件,并在index.ts内引用 创建一个类,这个类在创建好后有好几个地方都标红了 这是tslint的一些验证规则 一保存就会自动修复 ...
- TypeScript学习文档-基础篇(完结)
目录 TypeScript学习第一章:TypeScript初识 1.1 TypeScript学习初见 1.2 TypeScript介绍 1.3 JS .TS 和 ES之间的关系 1.4 TS的竞争者有 ...
- TypeScript: Angular 2 的秘密武器(译)
本文整理自Dan Wahlin在ng-conf上的talk.原视频地址: https://www.youtube.com/watch?v=e3djIqAGqZo 开场白 开场白主要分为三部分: 感谢了 ...
- TypeScript为Zepto编写LazyLoad插件
平时项目中使用的全部是jQuery框架,但是对于做webapp来说jQuery太过于庞大,当然你可以选择jQuery 2.*针对移动端的版本. 这里我采用移动端使用率比较多的zepto框架,他跟jqu ...
- TypeScript Vs2013 下提示Can not compile modules unless '--module' flag is provided
VS在开发TypeScript程序时候,如果import了模块有的时候会有如下提示: 这种情况下,只需要对当前TypeScript项目生成设置为AMD规范即可!
随机推荐
- Apache Sentry部署
三台hadoop集群,分别是master.slave1和slave2.下面是这三台机器的软件分布: master:NameNode.ZK.HiveMetaSotre.HiveServer2.Sentr ...
- IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列
1.引言 消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一. 消息从发送者到接收者的典型传递方式有两种: 1)一种我 ...
- Spring 静态代理+JDK动态代理和CGLIB动态代理
代理分为两种:静态代理 动态代理 静态代理:本质上会在硬盘上创建一个真正的物理类 动态代理:本质上是在内存中构建出一个类. 如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间.而动 ...
- 程序员IT计算机中常见英语单词
abstract 抽象的 abstract base class (ABC)抽象基类 abstract class 抽象类 abstraction 抽象.抽象物.抽象性 access 存取.访问 ac ...
- Linux系统 - 源码编译安装Nginx
什么是Nginx? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器,在高连接并发的情况下N ...
- Jenkins 忘记admin密码拯救方法
突然有一日发现自己忘记了jenkins的管理员密码,因为我一直登录的是另外一个非管理员账户.如果出现必须要使用管理员账户操作的,比如用户管理那里的,必须要管理员账号吧,这就尴尬了. 很方的我打开安装j ...
- 原生端与服务器通过sessionid实现session共享以及登录验证
注:原生端与服务器建立连接时产生的sessionid会变,跟上一次的不一样,为了保证sessionid一样,所以第一次服务器需要把sessionid返回给原生端,下一次与服务端会话时,原生端需要把这个 ...
- ArcMap中属性字段计算器(Field Calculator)的使用技巧
很多时候,我们在使用ArcGIS进行属性数据编辑时,需要批量修改某些字段值,这时候ArcGIS提供的属性字段计算器(Field Calculator)就是一把利器.下面我就Field C ...
- C语言学习之assert
C语言学习之assert assert (编程术语) 编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式.断言表示为一些布尔表达式,程序员相信 ...
- Gitlab仓库搭建及在linux/windows中免密使用gitlab(二)--技术流ken
Gitlab简介 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的 ...