一言以蔽之!TypeScript 是未来!
参考文章:
TypeScript 简介与优势
https://blog.csdn.net/Aria_Miazzy/article/details/105430400
与 JavaScript 和 Java 等主流语言相比,TypeScript 的运作方式显得与众不同!
第一步:程序员编写代码文本、形成文件、构成程序;
第二步:编译器将程序代码转换成抽象句法树(abstract syntax tree, AST);
AST 是去掉了空白、注释和缩进用的制表符或空格之后的数据结构。
第三步:编译器把 AST 转换成字节码;
第四步:字节码再传给运行时程序计算,得到最终结果。
概述:运行程序就是让运行时计算由编译器从源码解析得来的 AST 生成的字节码。
不同语言的具体细节有所不同,但整体大致如此!
TypeScript 不直接编译成字节码,而是编译成 JavaScript 代码,然后像往常那样执行 JavaScript 代码!
TypeScript 编译器生成 AST 之后,真正运行代码之前,TypeScript 会对代码做类型检查。
类型检查器:检查代码是否符合类型安全要求的特殊程序。
类型检查是 TypeScript 的魔力所在!
TS阶段——由 TSC 操作
第一步:TypeScript 源码 => TypeScript AST ;
第二步:类型检查其检查 AST ;
第三步:TypeScript AST => JavaScript 源码 ;
JS阶段——由浏览器、NodeJS或其他 JavaScript 引擎中的 JavaScript 运行时操作
第四步:JavaScript 源码 => JavaScript AST ;
第五步:AST => 字节码;
第六步:运行时计算字节码。
JavaScript 编译器和运行时通常聚在一个称为引擎的程序中。
程序员一般就是与引擎交互。
V8(驱动NodeJS、Chrome 和 Opera 的引擎)、SpiderMonkey(Firefox)、JSCode(Safari)和 Chakra(Edge)都是如此!
所以,JavaScript 看起来才像是一门解释型语言!
重申一下 TSC 将 TypeScript 转化成 JavaScript 时,不会考虑类型!也就意味着,类型不会对生成的 JavaScript 代码产生任何影响,类型只在类型检查这一步发挥作用!
类型检查器是程序分配类型时使用的一系列规则。
第一种:通过显式句法告诉编译器所有值的类型;
第二种:自动推导值的类型。
两种类型系统,各有利弊!
TypeScript 身兼两种类型系统!可以显式注解类型,也可以让 TypeScript 推导多数类型。
本书,只在必要时使用显式注解,多数情况下把工作交给 TypeScript 的推导功能。
类型系统特性 | JavaScript | TypeScript |
---|---|---|
类型是如何绑定的? | 动态 | 静态 |
是否自动转换类型? | 是 | 否(多数时候) |
何时检查类型? | 运行时 | 编译时 |
何时报告错误? | 运行时(多数时候) | 编译时(多数时候) |
① JavaScript 动态绑定类型,因此必须运行程序才能知道类型。此前,JavaScript 对类型一无所知!
② TypeScript 是渐进式类型语言。这意味着,在编译时知道所有类型能让 TypeScript 充分发挥作用,但在编译程序之间,并不需要知道全部类型。(存疑PS:前面说知道所有的类型能让 TypeScript 充分发挥作用,后面又说编译程序之前不需要知道全部类型!这么说啥意思啊!)
③ 渐进式类型特别便于把没有类型的 JavaScript 代码基迁移到具有类型的 TypeScript 。然而,除非你正处在迁移代码基的过程之中,否则应该实现 100% 的类型覆盖率!如无特殊说明,本书都采用这种策略!(存疑PS:没看懂啊这!)
渐进编译式语言在小修小改后可以快速重新编译,而不用重新编译整个程序(包括那些没有改动的部分)。
JavaScript 是弱类型语言!如果执行无效的操作,例如计算一个数与一个数组的和,JavaScript 将根据一系列规则判断你的真正意图!
下面以 JavaScript 表达式 3 + [1] 为例说明具体步骤:
第一步:JavaScript 发现 3 是一个数字,[1] 是一个数组;
第二步:由于使用 + ,JavaScript 假定你是想拼接二者;
第三步:JavaScript 把 3 隐式地转换为字符串,得到“3”;
第四步:JavaScript 把 [1] 隐式地转换为字符串,得到“1”;
第五步:把两个字符串拼接在一起,得到“31”。
我们可以更明确地表达意图(让 JavaScript 跳过第 1 步、第 3 步和第 4 步):
3 + [1]; // 求职结果为“31”
(3).toString() + [1].toString() // 求职结果为“31”(这就是表达了明确的意图)
JavaScript 会“自作聪明”,自动转换类型,而 TypeScript 发现无效的操作时则报错(如果表达了明确的意图, TypeScript 不会报错)!
总结,如果必须进行类型转换,请明确你的意图!
① 多数情况下,JavaScript 不在乎你使用的是什么类型,它会尽自己所能把你提供的值转换成预期的类型。
② TypeScript 会在编译时对代码进行类型检查。TypeScript 会对代码做静态分析,找出此类错误,在运行之前反馈给你。如果代码不能编译,很可能表明代码中有错误,在运行之前要修正。
为代码编辑器(如 VS Code)安装恰当的 TypeScript 扩展,若代码出错则会有提示。
① JavaScript 在运行时抛出异常;
其实,JavaScript 在解析程序之后、运行程序之前报告句法错误和部分缺陷(例如在同一个作用域中多次使用 const 声明同名变量)。如果是在构建过程中解析 JavaScrpt(例如使用 Babel ),错误则在构建时报告。
② TypeScript 在编译时报告句法和类型相关的错误,这些错误会在编辑器内显式,输入代码后立即有反馈;
③ 还有大量错误是TypeScript 在编译时无法捕获的,比如堆栈溢出、网络断连、恶意的用户输入等,这些属于运行时异常;
④ TypeScript 所能做的是把纯 JavaScript 代码中那些运行时错误提前到编译时报告!(PS:这应该就是 TypeScript 的核心功能了!)
第一步:安装 VS Code + Node JS(省略细节);
第二步:新建一个文件夹,初始化一个新的 NPM 项目
D:\MyFile\VSCodeProjects\hello-ts>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (hello-ts)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\MyFile\VSCodeProjects\hello-ts\package.json:
{
"name": "hello-ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)
D:\MyFile\VSCodeProjects\hello-ts>
第三步:安装 TSC 、TSLint 和 NodeJS 的类型声明
TSC 是通过 TypeScript 编写的命令行应用,需要通过 NodeJS 运行,我们称之为自托管编译器或自编译型编译器。
D:\MyFile\VSCodeProjects\hello-ts>npm install --save-dev typescript tslint @types/node
npm WARN deprecated [email protected]: TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.
added 42 packages, and audited 43 packages in 8s
3 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
D:\MyFile\VSCodeProjects\hello-ts>
每个 TypeScript 项目都应该在根目录中放一个名为 tsconfig.json
的文件,在该文件中定义要编译那些文件、把文件编译到哪个目录中,以及使用哪个版本的 JavaScript 运行。
第一步:在根目录下新建一个名为 tsconfig.json
的文件
第二步:使用代码编辑器输入下面内容
下面的内容应该得到重视!
{
"compilerOptions": {
"lib": ["ES2015"], // TSC 假定运行代码的环境有哪些 API ?包括 ES5 的 Function.prototype.bind 、ES2015 的 Object.assign 和 DOM 的 document.querySelector
"module": "commonjs", // TSC 把代码编译成哪个模块(CommonJS、SyatemJS、ES2015等)
"outDir": "dist", // TSC 把生成的 JavaScript 代码放在哪个文件夹中
"sourceMap": true,
"strict": true, // 检查无效代码时尽量严格。该选项强制所有代码都正确声明了类型。本书中所有示例都是用这个选项,你的 TS 项目也应如此!
"target": "ES2015" // TSC 把代码变成成哪个 JS 版本(ES3、ES5、ES2015、ES2016等)
},
"include": [ // 表示 TSC 在哪个目录下寻找 TypeScript 文件
"src"
]
}
上面只是一小部分选项, tsconfig.json
支持的选项有很多,而且一直有新的出现!实际上,这些选项很少改动,**偶尔改动的有:切换模块打包工具时修改 moudle 和 target 设置、编写在浏览器中运行的 TypeScript 时在 lib 中添加 dom (12 章有详细说明)、把现有 JavaScript 代码迁移到 TypeScript 时调整严格(strict)级别(见11.2节)。**此外,TSC 的很多选项可以通过命令设置,可用的命令通过 ./node_moudles/.bin/stc --help
命令查看
全局安装命令:npm i tslint --save -g
① tslint.json
文件用来保存代码风格上的约定!
② 它不是必要的,但强烈建议所有的 TypeScript 项目都使用它!
③ 可以使用 tslint --init
生成一个默认的 tslint.json
文件,可根据需求调整,下面是默认生成的内容:
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {},
"rulesDirectory": []
}
④ 作者的 tslint.json
文件
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"rules": {
"semicolon": false,
"trailing-comma": false
}
}
第一步:新建 src 目录和 index.ts 文件
第二步:编辑 index.ts 文件
console.log("Hello TypeScript!")
第三步:使用 TSC 编译 TypeScript
安装:npm install -g typescript
D:\MyFile\VSCodeProjects\hello-ts>tsc
第四步:运行 js 文件
D:\MyFile\VSCodeProjects\hello-ts\dist>node index.js
Hello TypeScript!
console.log("Hello TypeScript!")
let a = 1 + 2
let b = a + 3
let c = {
apple : a,
banana: b
}
let d = c.apple * 4