WHY JAVASCRIPT NEEDS TYPES
Types have a bad reputation for making code harder to read, adding unnecessary ceremony, and in general complicating things. In this blog post I’d like to show that a type system done right can help make code more readable and toolable without constraining the expressiveness of the language.
DOCUMENTATION FOR HUMANS AND MACHINES
First, I want to show how type annotations can be used as documentation for both humans and machines.
Let’s look at this function jQuery.ajax() and pretend that we are not familiar with it. What kind of information can we get from its signature?
jQuery.ajax(url, settings)
The only thing we can tell for sure is that the function takes two arguments. We can guess the types. Maybe the first one is a string and the second one is a configuration object. But it is just a guess and we might be wrong. We have no idea what options go into the settings object (neither their names nor their types) or what this function returns.
There is no way we can call this function without checking the source code or the documentation. Checking the source code is not a good option – the point of having functions and classes is to be able to use them without knowing how they are implemented. In other words, we should rely on their interfaces, not on their implementation.The only option we have here is to check the documentation. And there is nothing wrong with that. Except that it takes time.
Now, contrast it with a typed version.
ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;
interface JQueryAjaxSettings {
async?: boolean;
cache?: boolean;
contentType?: any;
headers?: { [key: string]: any; };
//...
}
interface JQueryXHR {
responseJSON?: any;
//...
}
It gives us a lot more information.
- The first argument of this function is a string.
- The settings argument is optional. We can see all the options that can be passed into the function, and not only their names, but also their types.
- The function returns a JQueryXHR object, and we can see its properties and functions.
This bring us to my first point.
Types serve as documentation for the programmer.
In addition, this information enables advanced autocompletion, navigation, and refactoring capabilities. Having such tools is almost a requirement for large projects. Without them programmers are afraid to change the code, which makes large-scale refactorings almost impossible. As Anders Hejlsberg puts it, you can build a large application in a dynamically-typed language, but you cannot maintain it. Without advanced tools a large code base is always in a semi-read-only state.
Types enable advanced tools.
TYPES PROVIDE A CONCEPTUAL FRAMEWORK FOR THE PROGRAMMER
A good design is all about well-defined interfaces. And it is much easier to express the idea of an interface in a language that supports them.
For instance, imagine a book-selling application where a purchase can be made by either a registered user through the UI or by an external system through some sort of an API.

As you can see, both classes play the role of a purchaser. Despite being extremely important for the application, the notion of a purchaser is not clearly expressed in the code. There is no file named purchaser.js. And as a result, it is possible for someone modifying the code to miss the fact that this role even exists.
function processPurchase(purchaser, details){
}
class User {
}
class ExternalSystem {
}
It is hard, just by looking at the code, tell what objects can play the role of a purchaser, and what methods this role has. We do not know for sure and we will not get much help from our tools. We have to infer this information manually, which is slow and error-prone.
Now, compare it with a version where we explicitly define the Purchaser interface.
interface Purchaser {
id: int;
bankAccount: Account;
}
class User implements Purchaser {}
class ExternalSystem implements Purchaser {}
The typed version clearly states that we have the Purchaser interface, and the User and ExternalSystem classes implement it. This brings us to my next point.
Types are useful for defining interfaces/protocols/roles. They provide a conceptual framework for the programmer.
It is important to realize that types do not force us to introduce extra abstractions. The Purchaser abstraction is present in the JavaScript version of the code, but it is not explicitly defined.
I’ve spent most of my career programming in Ruby and JavaScript, and I find these languages extremely powerful and flexible. But after working on sizeable apps written in these languages, I came to the conclusion that the lack of interfaces pushes developers toward building tightly coupled systems.
In a statically typed language boundaries between subsystems are defined using interfaces. Since Ruby and JavaScript lack interfaces, boundaries are not well expressed in code. Not being able to clearly see the boundaries, developers start depending on concrete types instead of abstract interfaces. And it leads to tight coupling. It is possible to build large decoupled systems in these languages, but it requires a lot of discipline.
STATICALLY TYPED LANGUAGES?
It may seem that I am advocating statically typed languages, but I am not. The arguments against a mandatory static type system are still sound.
- It complicates the language. Writing a mock library in JavaScript is an exercise that almost everyone can undertake. Doing similar stuff in Java is far more difficult.
- It constrains the expressiveness of the language.
- It requires type annotations even when they are not desirable (e.g., in a domain specific language).
What we want is something that combines the power of a dynamically typed language with the benefits of having explicit interfaces and type annotations.
OPTIONAL TYPE SYSTEMS
An optional type system does not require using type annotations. Type annotations are used to help you communicate your intent and get better tooling.
Optional type systems are forgiving. You do not have to satisfy the type checker. Quite the opposite, the type checker is there to help you find typos, search, and refactor. You do not completely rewrite your program to make the types work. If you are prototyping something, and duck typing works, just do not use types. Use them only when they add value.
It would not be completely fair to say that optional typing is only good stuff without any drawbacks. It still adds some complexity to the language (nothing compared to a mandatory static type system though).Also, to fully see the benefits of such a system you need more sophisticated tools than a plain text editor. But because of the reasons I outlined in this blog post, I think it is worth paying this price.
TYPED JAVASCRIPT
I wrote the original version of this blog post some time ago, and called it “I Wish Ruby Had Interfaces”. Back then I was a Rails developer. And I was extremely frustrated by working on a very large Rails code base, where some refactorings were taking months to finish. There was no hope Ruby would get an optional type system, so it was just a rant.
This time it is different. The JavaScript community is embracing the idea of optional types. TypeScript has become a robust tool used in production at many companies. AtScript, and Flow are new projects in this area. I am really excited to see what typed JavaScript community will look like in a few years.
WHY JAVASCRIPT NEEDS TYPES的更多相关文章
- JavaScript data types and data structures
JavaScript data types and data structures Programming languages all have built-in data structures, b ...
- JavaScript & Error Types
JavaScript & Error Types JavaScript提供了8个错误对象,这些错误对象会根据错误类型在try / catch表达式中引发: Error EvalError Ra ...
- [Javascript] Manage Application State with Immutable.js
Learn how Immutable.js data structures are different from native iterable Javascript data types and ...
- JavaScript 中的数字和日期类型
本章节介绍如何掌握Javascript里的数字和日期类型 数字EDIT 在 JavaScript 里面,数字都是双精度浮点类型的 double-precision 64-bit binary form ...
- JavaScript Transpilers: 为什么需要用它们?Babel的使用介绍。
英文原文 https://scotch.io/tutorials/javascript-transpilers-what-they-are-why-we-need-them 摘译(文章内的代码有些过期 ...
- Javascript——概述 && 继承 && 复用 && 私有成员 && 构造函数
原文链接:A re-introduction to JavaScript (JS tutorial) Why a re-introduction? Because JavaScript is noto ...
- 深入理解 JavaScript中的变量、值、传参
1. demo 如果你对下面的代码没有任何疑问就能自信的回答出输出的内容,那么本篇文章就不值得你浪费时间了. var var1 = 1 var var2 = true var var3 = [1,2, ...
- A re-introduction to JavaScript (JS Tutorial) 转载自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
A re-introduction to JavaScript (JS Tutorial) Redirected from https://developer.mozilla.org/en-US/do ...
- 实现JavaScript继承
使用TypeScript或者ES2015+标准中的extends关键字是很容易实现继承的,但这不是本文的重点.JS使用了基于原型(prototype-based)的继承方式,extends只是语法糖, ...
随机推荐
- 《FDTD electromagnetic field using MATLAB》读书笔记之一阶、二阶偏导数差商近似
- 关于const 和指针
这个很久之前就很困扰的问题,现在再理一下: 1,指向const对象的指针 >C++强制要求指向const对象的指针也必须具有const特性!!!也就是不能把一个const对象的地址赋给一个非co ...
- CH1807 Necklace
题意 背景 有一天,袁☆同学绵了一条价值连城宝石项链,但是,一个严重的问题是,他竟然忘记了项链的主人是谁!在得知此事后,很多人向☆同学发来了很多邮件,都说项链是自己的,要求他归还(显然其中最多只有一个 ...
- 每日一条 Git 命令:git merge remote master
每日一条 Git 命令:git merge remote master 当远程的分支更新后,需要将自己的代码与远程的分支合并就用以下这个命令合并. git merge remote master 如果 ...
- load/domContentLoaded事件、异步/延迟Js 与DOM解析
一.DOMContentLoaded 与 load事件 关于load和DOMContentLoaded事件,mdn对于它们是这样描述的: DOMContentLoaded mdn文档地址:https: ...
- Weex入门与进阶指南
Weex入门与进阶指南 标签: WeexiOSNative 2016-07-08 18:22 59586人阅读 评论(8) 收藏 举报 本文章已收录于: iOS知识库 分类: iOS(87) 职 ...
- 【转】Java中的内部类和匿名类
Java内部类(Inner Class),类似的概念在C++里也有,那就是嵌套类(Nested Class),乍看上去内部类似乎有些多余,它的用处对于初学者来说可能并不是那么显著,但是随着对它的 ...
- Java 运用流传输文件
实例1 package IO; import java.io.FileReader; import java.io.FileWriter; import java.io.Reader; import ...
- Bootstrap-Other:UI 编辑器
ylbtech-Bootstrap-Other:UI 编辑器 1.返回顶部 1. Bootstrap UI 编辑器 以下是 15 款最好的 Bootstrap 编辑器或者是在线编辑工具. 1. Boo ...
- 操作表单域中的value值
HTML <form action=""> <input type="radio" name="sex" value=&q ...