为什么使用TypeScript
TypeScript的主要卖点之一是,它允许您在当前(ES3和ES5级别)JavaScript引擎(例如当前的浏览器和Node.js)中使用ES6以及更高版本的许多功能。在这里,我们将深入探讨为什么这些功能很有用,然后深入探讨如何在TypeScript中实现这些功能。
注意:并非所有这些功能都可以立即添加到JavaScript中,但是可以为您的代码组织和维护提供强大的实用工具。还要注意,您可以随意忽略对您的项目没有意义的任何构造,尽管最终最终会使用其中的大部分;)
主要目标
TypeScript有两个主要目标:
- 提供JavaScript 的可选类型系统。
- 提供从将来的JavaScript版本到当前JavaScript引擎的计划功能
对这些目标的渴望在下面被激发。
TypeScript入门
TypeScript编译为JavaScript。JavaScript是您实际要执行的(在浏览器或服务器上)。因此,您将需要以下内容:
- TypeScript编译器(OSS 在源代码和NPM上可用)
- 一个TypeScript编辑器(如果需要,可以使用记事本,但我使用vscode🌹编写的扩展名。很多其他IDES也支持它)
TypeScript版本
除了使用稳定的 TypeScript编译器,我们还将在本书中介绍许多可能尚未与版本号关联的新内容。我通常建议人们使用夜间版本,因为随着时间的推移,编译器测试套件只会捕获更多错误。
您可以在命令行上将其安装为
npm install -g typescript@next
现在,命令行将tsc
是最新的和最大的。各种IDE也支持它,例如
- 您可以通过创建
.vscode/settings.json
以下内容来要求vscode使用此版本:
{
"typescript.tsdk": "./node_modules/typescript/lib"
}
获取源代码
本书的源代码可在github资料库https://github.com/basarat/typescript-book/tree/master/code中找到,大多数代码示例都可以复制到vscode中,您可以直接使用它们。对于需要额外设置的代码示例(例如npm模块),我们将在显示代码之前将您链接到该代码示例。例如
this/will/be/the/link/to/the/code.ts
//这将是正在讨论的代码
通过开发设置,让我们跳入TypeScript语法。
TypeScript类型系统
您可能想知道“ 为什么要向JavaScript添加类型? ”
类型具有提高代码质量和可理解性的成熟能力。大型团队(Google,Microsoft,Facebook)一直在得出这一结论。特别:
- 类型在进行重构时可以提高敏捷性。对于编译器来说,捕获错误比使事情在运行时失败更好。
- 类型是您可以拥有的最佳文档形式之一。函数签名是一个定理,函数体是证明。
但是,类型具有不必要的礼仪性。TypeScript在保持尽可能低的进入障碍方面非常特别。就是这样:
JavaScript Or TypeScript
TypeScript为JavaScript代码提供了编译时类型安全性。鉴于其名称,这不足为奇。很棒的是类型是完全可选的。您的JavaScript代码.js
文件可以重命名为.ts
文件,并且TypeScript仍然会给您有效的.js
等效于原始JavaScript文件的信息。TypeScript 有意且严格地是带有可选类型检查的JavaScript的超集。
类型可以是隐式的
TypeScript将尝试推断尽可能多的类型信息,以便在代码开发过程中以最小的生产成本为您提供键入安全性。例如,在下面的示例中,TypeScript将知道foo是number
下面的类型,并将在第二行显示错误,如下所示:
var foo = 123 ;
foo = '456' ; //错误:无法将`string`分配给`number`
// foo是数字还是字符串?
这种类型的推断是有动机的。如果您执行本示例中所示的操作,那么在其余代码中,您将无法确定foo
a number
或a string
。大型多文件代码库中经常会出现此类问题。稍后我们将深入研究类型推断规则。
类型可以是显式的
如前所述,TypeScript将尽可能安全地进行推断。但是,您可以使用注释来:
- 提供有关编译器的帮助,更重要的是为下一个必须阅读您的代码的开发人员提供文档资料(这可能是您的未来!)
- 强制编译器看到的就是您认为应该看到的。那就是您对代码的理解与代码的算法分析(由编译器完成)匹配。
TypeScript使用在其他可选注释语言(例如ActionScript和F#)中流行的后缀类型注释。
var foo : number = 123 ;
因此,如果您做错了什么,编译器将报错,例如:
var foo : number = '123' ; //错误:无法将`string`分配给`number`
在下一章中,我们将讨论TypeScript支持的所有注释语法的所有详细信息。
类型是结构性的
在某些语言(特别是名义上的语言)中,静态类型会导致不必要的仪式,因为即使您知道代码可以很好地工作,语言语义也会迫使您复制内容。这就是为什么像东西automapper为C#是至关重要的为C#。在TypeScript中,因为我们确实希望对JavaScript开发人员来说具有最小的认知过载,所以很容易,所以类型是结构化的。这意味着鸭子类型是一流的语言构造。考虑以下示例。该函数iTakePoint2D
将接受包含期望的所有事物(x
和y
)的任何事物:
interface Point2D {
x: number;
y: number;
}
interface Point3D {
x: number;
y: number;
z: number;
}
var point2D: Point2D = { x: 0, y: 10 }
var point3D: Point3D = { x: 0, y: 10, z: 20 }
function iTakePoint2D(point: Point2D) { /* do something */ }
iTakePoint2D(point2D); // exact match okay
iTakePoint2D(point3D); // extra information okay
iTakePoint2D({ x: 0 }); // Error: missing information `y`
类型错误不会阻止JavaScript发出
为了使您轻松将JavaScript代码迁移到TypeScript,即使存在编译错误,默认情况下TypeScript 也会尽其所能发出有效的JavaScript。例如
var foo = 123 ;
foo = '456' ; //错误:无法将`string`分配给`number`
而js则不会提示错误:
var foo = 123 ;
foo = '456';
因此,您可以将JavaScript代码逐步升级到TypeScript。这与其他许多语言编译器的工作方式有很大不同,这也是迁移到TypeScript的另一个原因。
类型可以是环境类型
TypeScript的主要设计目标是使您可以安全轻松地使用TypeScript中的现有JavaScript库。TypeScript通过声明来做到这一点。TypeScript为您提供了要在声明中投入多少精力的滑动比例,投入更多的精力就可以获得更多的类型安全性和代码智能。请注意,DefinitelyTyped社区已经为您编写了大多数流行JavaScript库的定义,因此对于大多数用途而言:
- 定义文件已经存在。
- 或者至少,您已经拥有大量经过严格审查的TypeScript声明模板
作为如何编写自己的声明文件的快速示例,请考虑一个简单的jquery示例。默认情况下(正如好的JS代码所期望的那样),TypeScript希望您var
在使用变量之前声明(即在某处使用)
$('.awesome').show(); // Error: cannot find name `$`
作为快速解决方案,您可以告诉TypeScript实际上确实有一个叫做$
:
declare var $: any;
$('.awesome').show(); // Okay!
如果您愿意,可以基于此基本定义并提供更多信息以帮助保护您免受错误的侵害:
declare var $: {
(selector:string): any;
};
$('.awesome').show(); // Okay!
$(123).show(); // Error: selector needs to be a string
一旦您对TypeScript有更多了解(例如interface
和之类的东西any
),我们将在后面详细讨论为现有JavaScript创建TypeScript定义的细节。
将来的JavaScript =>现在
TypeScript提供了ES6中为当前JavaScript引擎计划的许多功能(仅支持ES5等)。TypeScript团队正在积极添加这些功能,并且随着时间的推移,这个列表只会变得越来越大,我们将在其自己的部分中进行介绍。但是,就像一个标本一样,这是一个类的示例:
class Point {
constructor(public x: number, public y: number) {
}
add(point: Point) {
return new Point(this.x + point.x, this.y + point.y);
}
}
var p1 = new Point(0, 10);
var p2 = new Point(10, 20);
var p3 = p1.add(p2); // { x: 10, y: 30 }
和可爱的胖箭头功能:
var inc = x => x+1;
摘要
在本节中,我们为您提供了TypeScript的动机和设计目标。通过这种方式,我们可以深入研究TypeScript的细节。
[](接口是开放式的)[](类型推断规则)[](覆盖所有注释)[](覆盖所有环境:也没有运行时强制执行)[](。ts与.d.ts)
翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/why-typescript.md