TypeScript的主要特性

  1. 超集 :TypeScript 是 JavaScript 的一个超集
  2. 类型系统 :正如其名,TypeScript在JavaScript的基础上,包装了类型机制,使其变身为静态类型语言。
  3. 编辑器功能 :增强了编辑器和IDE功能,包括代码补全、接口提示、跳转到定义、重构等
  4. 错误提示 :可以在编译阶段就发现大部分错误,帮助调试程序

JavaScript的特点

  1. JavaScript 是一种轻量级的解释性脚本语言
  2. JavaScript 是弱类型、动态类型语言,允许隐式转换,只有运行时才能确定变量的类型

超集

也就是说,你不是“不用JavaScript开发而改用TypeScript”了,本质上开发语言还是JavaScript,只是TypeScript在JavaScript的基础上扩展了新的特性,JavaScript该有的,TypeScript都有。

为什么TypeScript的静态类型能增强代码的可读性和可维护性

TypeScript通过类型注解提供编译时的静态类型检查。

编程语言可简单地看作对一系列变量的处理,变量从某个维度上讲是建立在类型系统上的,就像客观世界万物也是由各种类型组成。
首先是基础的类型,代表计量的数字类型,代表身份的字符串类型,代表逻辑是否的布尔类型,代表集合的对象(含数组),代表存在性的’空’;
然后是各种自定义的类型,某样生活用品、某种职业,即面对对象编程里的对象、类、接口的概念;
这也符和人对事物的普遍认知,从一个类型,就能大致知道它是什么、怎么能得到它、它能做什么,减少查阅、理解、校验的过程,最好的情况是无需将关注点转移……

最强大地方的还不在于基础类型的注解,而在于自定义类型(接口或类)、内置对象(HTMLElement,Event等)的提示。

以confirmAddBook这个组件中方法和book.service这个服务层的函数为例。

1. 它是什么

以入参book为例:

  • JavaScript

去bookService.js看看,它是http请求传给后端的参数,是个对象。
到接口文档看看。

  • TypeScript

是个Book类型的对象。
操作编辑器能直接显示book含有id, name, author, isNew属性,每个属性是什么类型,是否可选。

2. 怎么能得到它:

以组件成员变量books为例:

  • JavaScript

去data处看看,初始值是null(因为某些需要,初始值不能是[]),最多从命名推测应该是个数组,但数组是怎么构成的,还得回想或查一下model层、view层的设计。

  • TypeScript

操作编辑器能直接显示books的类型是Book[],即Book类型的单项构成的数组,于是操作数组合并。

3. 它能做什么

this.bookService.addBook 是调用服务层的方法,它返回什么?

  • JavaScript

去查接口文档

  • TypeScript

返回 Observable<Book> ,订阅之,得到的数据是Book类型——一本书。

  1. // confirmAddBook.js
  2. export default {
  3. data() {
  4. return {
  5. books: null,
  6. isShowModal = false;
  7. }
  8. }
  9. confirmAddBook(book) {
  10. this.bookService.addBook(book).then(book => {
  11. this.books = [book, ...this.books];
  12. this.isShowModal = false;
  13. });
  14. }
  15. }
  1. // confirmAddBook.ts
  2. interface Book {
  3. id: number;
  4. name: string;
  5. author: string;
  6. isNew: boolean
  7. }
  8. export class BookListComponent implements OnInit {
  9. books: Book[] = [];
  10. isShowModal = false;
  11. confirmAddBook(book: Book): void {
  12. this.bookService.addBook(book as Book).subscribe(book => {
  13. this.books = [book, ...this.books];
  14. this.isShowModal = false;
  15. });
  16. }
  17. }
  1. // book.service.js
  2. function addBook(book: Book) {
  3. // ...
  4. }
  1. // book.service.ts
  2. function addBook(book: Book): Observable<Book> {
  3. // ...
  4. }

可维护性

上述的同样应用于可维护性上。

此外:

JavaScript是函数式编程,参数的传递是核心之一也是最容易出错出bug的地方之一,有了类型注解,就能一目了然得知道需要传递什么样的参数,防止遗漏、误删,
此外,在编译阶段的类型检查和错误提示,可以取代很多单元测试所需要的工作。

引用类型数据
相较于基本数据类型,引用类型的数据的维护难度更大,有了接口定义,能方便。

增强的编辑器功能

错误提示

  1. JSON.stringify和JSON.parse
  2. 表单输入的数字,获取到的是字符串
  3. 函数参数的检查

无论是输入时,还是检查时

  1. 最强大的不在于JS类型的提示,而在于自定义类型(接口或类)的提示

具体项的提示;不用切换视口

  1. TypeScript提供了静态的代码分析,在编译之前,可以过滤掉大部分错误,而JS是无法做到的。
  2. 基于类的面向对象编程
  3. 尽量使用严格比较符号,如:===

缺点

  1. 写类型定义会一定程度上降低开发效率,但是在大项目中可折衷。

    典型问题

    1. // {get: jasmine.Spy4}紧跟在:之后,所以它是一个对象类型(接口)
    2. // 所以jasmine.Spy4是一个类型而不是属性值
    3. let httpClientSpy: {get: jasmine.Spy4}

可读性和可维护性

JavaScript所能做的

  1. 依靠编码规范,命名、注释(特别是类型的注释)
  2. 对自己编写代码和维护他人代码的熟悉度,
  3. 编辑器的搜索、替换、重构等功能,代码提示、补全;

搜索替换易出错

  1. 自动测试、手动测试
  2. 运行错误的提示;

以上这些,要么都是需要发挥人的主观能动性,要么,并且这是基本的要求,每种语言都应做到。