为什么TypeScript解决不了问题


发布者 andrewleeson  发布时间 1396535265211
关键字 心得体会 

我以前写过关于JavaScript编程陷阱和一些可能解决此难题的方法的文章。一个可能的解决方法是TypeScript。这是一个由微软开发的开源项目语言,它是JavaScript的一个类型化超集,最终能编译生成JavaScript。它是在JavaScript的基础上增加类、模块、接口和可选的类型声明而实现的。编译时,类型声明将被擦除,生成ECMAScript 3 兼容的代码。如果可能的话,TypeScript试图将让语法和语义匹配的建议提交给ECMAScript 6。建议的很多地方还在变化不定,而且最终的规则是什么还尚不清楚,所以我们必须要看到TypeScript是如何有能力处理它的。

修复问题

TypeScript用类型、类和接口来增强JavaScript。一些人认为那些正是JavaScript的问题所在。其实不然。JavaScript的问题并不是因为它是一个无类的基于面向对象的动态类型原型语言。其实这才是JavaScript的实力所在。JavaScript的问题在于它是一个设计不当的语言,充满了许多隐藏的陷阱等着那些没有防备的开发人员来踩。

 

我认为JavaScript的弱类型是其最大的亮点,但类型检查却名过其实了。TypeScript增加了一些东西,但却付出了代价。这不是我愿意付出的代价。
 
——JavaScript: The Good Parts 的作者 Douglas Crockford

谁来维护类型定义

TypeScript增加了可选的类型声明,但当与已经存在的JavaScript库相互作用时,就没有类声明了,而且TypeScript的很多优势将不复存在。为了处理这个问题,TypeScript支持类型定义文件。这些文件给已存在的JavaScript库提供丢失的类型声明。给你想使用的JavaScript库提供好的类型定义文件是你很好的使用TypeScript的重要内容。微软指出明确类型化的工程作为类型定义的根源供流行的JavaScript库使用。然而,如果你想使用的库不够流行或太新了,那么会怎样呢?或者,虽然有类型定义,但与你需要使用的库版本不符,会怎样?你有真正关注过许多这些JavaScript库发布新版本有多频繁吗?你怎么敢肯定类型定义是正确的?它们只是潜在发展问题的更多来源而已。如果不是库作者来维护这些库,任何这些库的附件绑定成为额外让人头疼的根源。最近,当有些新的Ember.js库的NuGet包过期,且支持jQuery的包无法正确地并排支持1倍,2倍代码行的安置时,我在社区维护包(不是TypeScript或明确类型化的)上遇到了类似的问题。

还是用JavaScript

TypeScript的真正问题包含在一句话中——“它是JavaScript的超集”。这意味着所有合法的JavaScript程序同时也是合法的TypeScript程序。TypeScript没有修复任何已在 ECMA Script 5中修复之外的问题。所以,比如说,非严格的等号==还仍然存在,且起严格的等号===更精简更自然。仍然存在分号插入的陌生感。在有些情况下,这些附加的特性实际上使开发人员更有可能将丢弃语义上错误的心理模型,然后径直走到陷阱中去。类让这个不变的this关键词变得更加混乱。例如,来自TypeScript的Greeter类的this的用法让在感到迷惑:

class Greeter {
	greeting: string;
	constructor(message: string) {
		this.greeting = message;
	}
	greet() {
		return "Hello, " + this.greeting;
	}
}

我们不禁觉得Greeter类方法里this关键词应该始终引用一个Greeter的实例。然而,JavaScript中this的语义没有改变:

var greeter = new Greeter("world");
var unbound = greeter.greet;
alert(unbound());

上面的代码将打印出“Hello,undefined”而不是想当然的“Hello,World”。

更新

一个评论(alleycat5Reddit上的评论)指出TypeScript只片面的处理==问题,因为当如果已有类型信息时用==进行比较会产生类型错误。                                          
var a = "ssdf";
var b = 5;
alert(a==b); // "Operator '==' cannot be applied to types 'string' and 'number'."

 然而,如果任意一个变量有Objectany类型,将不会产生类型错误且会继续计算这宽松比较的结果。

TypeScript并不是解决方案

我认为TypeScript并不是这个问题的解决方案。或者更精确的来说,它可能是其它问题的解决方案。如果你不顾一切地喜欢JavaScript。但如果你想让它有类、模块、接口和静态类型化,那么TypeScript就是一个解决方案。我推断,随着时间的推移,人们会逐步的认识到TypeScript并没有消除JavaScript中存在的陷阱,通过提供让人错觉的安全只会让其变得更迷惑。TypeScript只会成为另一个被小部分开发人员使用的web开发边缘的工具。

本文是4篇连载文章的第2篇:

  • 第二篇  本文





回复 (1)
微信扫码 立即评论