EffectiveTypeScript:精进TypeScript代码的个实践方法pdf下载pdf下载

EffectiveTypeScript:精进TypeScript代码的个实践方法百度网盘pdf下载

作者:
简介:本篇主要提供EffectiveTypeScript:精进TypeScript代码的个实践方法pdf下载
出版社:
出版时间:2021-11
pdf下载价格:0.00¥

免费下载


书籍下载


内容介绍

产品特色

内容简介

·学习TypeScript的类型系统的基本内容。

·设计类型,让你的代码更安全,更易懂。

·使用类型推断,用最少的类型标注来获得完全的安全。

·战术性利用any类型。

·了解TypeScript中的依赖关系和类型声明文件是如何工作的。

·将你的JavaScript代码库成功地迁移到 TypeScript。

作者简介

Dan Vanderkam是Sidewalk Labs的首席软件工程师,也是TypeScript NYC Meetup的联合创始人。作为开源项目的长期贡献者,他此前曾在西纳山的伊坎医学院工作,并在谷歌负责数十亿用户使用的搜索功能。

精彩书评

“本书探讨了我们在使用TypeScript时最常见的问题,并提供了实用的、注重结果的建议。无论你的TypeScript经验水平如何,你都可以从这本书中学到一些东西。”

——Ryan Cavanaugh

微软 TypeScript 的工程负责人

“这本书充满了实用的技巧,有必要放在每个专业的TypeScript开发者的办公桌上。即使你认为你已经了解TypeScript了,你也不会后悔拥有这本书的。”

——Yakov Fain

Java Champion

目录

目录
前言 .1
第1 章 了解TypeScript 11
条款1:理解 TypeScript 与 JavaScript 的关系 11
要记住的事情 18
条款2:知道你在使用哪个 TypeScript 选项 18
要记住的事情 22
条款3:理解代码的生成是独立于类型的 . 22
类型错误的代码仍会产生输出 23
你无法在运行时检查 TypeScript 类型 24
类型操作不能影响运行时的值 26
运行时类型可能与声明类型不一样 . 27
你不能基于 TypeScript 类型来重载一个函数 . 28
TypeScript 类型对运行时的性能没有影响 29
要记住的事情 30
条款4:习惯结构类型(Structural Typing). 30
要记住的事情 35
条款5:限制使用any 类型 35
any 类型没有类型安全 36
any 类型会让你打破契约 36
any 类型没有语言服务 37
any 类型会掩盖重构代码时的错误 38
any 类型遮蔽了你的类型设计 . 39
any 类型破坏了你对类型系统的信心 40
要记住的事情 40
第2 章 TypeScript 的类型系统 41
条款6:使用你的编辑器来询问和探索类型系统 41
要记住的事情 46
条款7:将类型视为价值的集合 . 46
要记住的事情 53
条款8:知道如何分辨符号是类型空间还是值空间 . 54
要记住的事情 60
条款9:优先选择类型声明而不是类型断言 60
要记住的事情 64
条款10:避免对象包装类(String,Number,Boolean,Symbol,BigInt) 64
要记住的事情 68
条款11:认识额外属性检查的局限性 . 68
要记住的事情 72
条款12:尽可能将类型应用于整个函数表达式 . 72
要记住的事情 75
条款13:了解类型(type)和接口(interface)的区别 75
要记住的事情 81
条款14:使用类型操作和泛型来避免重复自己的工作 81
要记住的事情 90
条款15:为动态数据使用索引签名 . 91
要记住的事情 95
条款16:优先选择 Array、Tuple 和 ArrayLike,而不是数字索引签名. 95
要记住的事情 99
条款17:使用 readonly 避免值变(Mutation)相关的错误. 99
要记住的事情 107
条款18:使用映射类型来保持值的同步 . 107
要记住的事情 110
第3 章 类型推断 111
条款19:避免你的代码被可推断类型弄得混乱不堪 112
要记住的事情 119
条款20:不同的类型使用不同的变量 119
要记住的事情 122
条款21:理解类型扩展 122
要记住的事情 126
条款22:理解类型收缩 127
要记住的事情 130
条款23:一次性构建对象 131
要记住的事情 134
条款24:在使用别名时要保持一致 134
要记住的事情 138
条款25:使用async 函数代替异步代码的回调 138
要记住的事情 144
条款26:了解类型推断中如何使用上下文 144
元组类型 . 146
对象 148
回调 148
要记住的事情 149
条款27:使用函数式构造和库来帮助类型流转 150
要记住的事情 155
第4 章 类型设计 156
条款28:倾向选择总是代表有效状态的类型 156
要记住的事情 162
条款29:宽进严出 163
要记住的事情 166
条款30:不要在文档中重复类型信息 167
要记住的事情 169
条款31:将空值推到你的类型边界上 169
要记住的事情 173
条款32:优选接口的联合,而不是联合的接口 173
要记住的事情 177
条款33:选择更精确的字符串类型的替代类型 178
要记住的事情 182
条款34:宁愿选择不完整的类型,也不选择不准确的类型 . 183
要记住的事情 187
条款35:从 API 和规范而不是从数据中生成类型 . 188
要记住的事情 194
条款36:使用你的问题域语言命名类型 . 194
要记住的事情 197
条款37:考虑加“烙印”来实现名义类型 197
要记住的事情 201
第5 章 和 Any 一起工作. 202
条款38:为 Any 类型使用最窄的范围 . 202
要记住的事情 205
条款39:比起普通的 any,选择更精确的 any 变体 . 205
要记住的事情 207
条款40:在类型良好的函数中隐藏不安全的类型断言 207
要记住的事情 210
条款41:理解 any 演变 210
要记住的事情 214
条款42:对未知类型的值使用 unknown 而不是 any 214
要记住的事情 218
条款43:选择类型安全的方法而不是猴子补丁 218
要记住的事情 221
条款44:追踪你的类型覆盖率以防止类型安全中的回归问题 221
要记住的事情 224
第6 章 类型声明和 @types 225
条款45:把 TypeScript 和 @types 放在 devDependencies 中 225
要记住的事情 227
条款46:了解类型声明中涉及的三个版本 228
要记住的事情 232
条款47:导出所有出现在公有 API 中的类型 232
要记住的事情 233
条款48:使用 TSDoc 来编写 API 注释 234
要记住的事情 237
条款49:提供回调中 this 的类型 237
要记住的事情 242
条款50:优先选择条件类型,而不是重载声明 242
要记住的事情 245
条款51:反映类型以切断依赖 . 245
要记住的事情 246
条款52:警惕测试类型时的陷阱 247
要记住的事情 252
第7 章 编写和运行你的代码 . 253
条款53:使用 ECMAScript 特性,而非 TypeScript 特性 253
枚举 254
参数属性 . 256
命名空间和三斜线导入 258
装饰器 258
要记住的事情 259
条款54:了解如何迭代对象 259
要记住的事情 262
条款55:了解 DOM 的层次结构 . 262
要记住的事情 269
条款56:不要依赖私有访问修饰符(private) 来隐藏信息 269
要记住的事情 272
条款57:使用 Source Maps 来调试 TypeScript 272
要记住的事情 276
第8 章 迁移到TypeScript . 277
条款58:编写现代 JavaScript 278
使用 ECMAScript 模块 279
使用类而不是原型 . 279
使用 let/const 代替 var . 281
使用 for-of 或数组方法代替 for(;;) 282
优先选择箭头函数而不是函数表达式 282
使用对象字面量的简写形式和解构赋值 . 283
使用默认函数参数 . 285
使用 async/await 代替原始的 Promise 或 Callback 286
不要把 use strict 放在 TypeScript 中 . 287
要记住的事情 288
条款59:使用 @ts-check 和 JSDoc 来尝试 TypeScript 288
未声明的全局变量 . 289
未知的库 . 289
DOM 问题 290
不准确的 JSDoc 291
要记住的事情 293
条款60:通过 allowJs 混合使用 TypeScript、JavaScript 293
要记住的事情 295
条款61:将模块逐个转换到依赖关系图上 295
未声明的类成员 296
类型不断变化的值 . 298
要记住的事情 300
条款62:在启用 noImplicitAny 之前,不要认为迁移已经完成 . 301
要记住的事情 302

前言/序言

前言
2016 年春天,我拜访了工作在谷歌旧金山办公室的老同事 Evan Martin,并像过去一样询问了他正沉迷于哪个领域。鉴于他每年的答案都十分广泛、不可预知却又十分有趣,所以这些年,我问过他很多次这个问题,他的回答包括但不限于C++ 构建工具、Linux 音频驱动、在线纵横字谜、Emacs 插件。而这一次,Evan 的回答是他正沉迷于 TypeScript 和 Visual Studio Code。我十分惊讶!我曾在不久前听说过 TypeScript,但彼时我对它的了解仅限于它是由微软创造出来的,且误以为它和 .NET 有关。作为一个 Linux 的忠实用户,我实在难以相信 Evan 竟然投向了微软的怀抱。
但在 Evan 向我展示了 Visual Studio Code 和 TypeScript 学习乐园(TypeScript Playground)之后,我立刻改变了我的想法。一切运转得都很快,代码智能使得构建类型系统的心智模型变得很容易。在为 Closure 编译器在 JSDoc 注释中编写了多年的类型标注之后,这给我的感觉是 TypeScript 像是真正工作的类型化 JavaScript。微软已经在 Chromium 之上建立了一个跨平台的文本编辑器?也许这是一种值得学习的语言和工具链。
我当时刚刚加入了 Sidewalk Labs ,正在写我们的第一个 JavaScript。代码库还很小,Evan 和我可以在接下来的几天时间内把它全部转换成 TypeScript。从那以后我就被迷住了。TypeScript 不仅仅是一个类型系统,它还带来了一整套快速易用的语言服务。TypeScript 不仅让 JavaScript 开发更安全,而且让它更有趣!
本书面向的读者群
“Effective”系列丛书旨在成为他们描述主题的“标准第二本书”。如果你有使用 JavaScript 和 TypeScript 的实践经验,那么你将能充分利用有效的TypeScript。我写本书的目的不是教你如何使用 TypeScript 或 JavaScript,而是帮助你从一个初级或中级用户成长成为一个专家。本书中的内容可以帮助你利用 TypeScript 及其生态系统建立工作的心智模型,让你意识到要避免的陷阱,并引导你以最有效的方式使用 TypeScript 的许多功能。参考书会解释一门编程语言可以让你做某些事的五种方法,而 “Effective 系列丛书则会告诉你它们分别是哪五种方法及为什么。
TypeScript 在过去几年内得到了迅速发展,但我希望它已经稳定到足以使本书的内容在今后几年内都能保持有效。本书主要关注语言本身,而不是任何框架或构建工具。你既找不到任何关于如何对 TypeScript 使用 React 或 Angular的示例,也找不到如何配置 TypeScript 以使用 Webpack、Babel 或 Rollup 的示例。本书的建议适合所有的 TypeScript 用户。
我为什么写本书
我刚到谷歌工作时,拿到了《Effective C++(第三版)》。它不像我读过的任何其他编程书。它没有试图让初学者知道如何能够接触到它,也没有试图成为一个完整的语言指南。它没有告诉你 C++ 的不同特性,而是通过几十个简短、具体而又带有具体实例的条款告诉你应该或不应该如何使用它们。
通过阅读这些例子,你能清楚明白地在日常工作中使用这门语言。我以前也编写C++ 程序,但从那之后我开始能够舒服地使用它,并知道如何思考它给予我的选择。后来在读《Effective Java》和《Effective JavaScript》时,它们也带给了我相似的体验。
如果你已经习惯了使用几种不同的编程语言,那么直接跳进一种新的编程语言的奇怪角落,是一种有效的方法,这样可以挑战你的思维模式,了解这门语言的不同之处。我在写本书的过程中收获了大量关于 TypeScript 的知识,我希望你在阅读本书的过程中也能收获同样的体验!
本书结构
本书是由“条款”构成的,每一个条款都是一篇简短的技术文章,为你提供有关TypeScript 的某些方面的具体建议。这些条款按主题分成章节,但你可以随意翻阅你最感兴趣的条款。
每个条款的标题传达了该条款的关键点。在使用 TypeScript 时,这些都是你应该记住的,所以你有必要浏览一下目录,让它们进入你的脑海。例如,如果你正在编写文档,并且有不应该编写类型信息的困扰,那么你将知道去阅读条款30:不要在文档中重复类型信息。
条款里面的文本激发了标题中的建议,并用具体的例子和技术论据来支持它。本书中的几乎每一点都是通过示例代码来演示的。我倾向通过看例子和略读散文来阅读技术书籍,我想你也会做类似的事情。我希望你能读到这篇文章和解释!但是,如果你略过这些例子,你还是能够获得主要的观点的。
阅读完条款后,你应该明白为什么它能帮助你更有效地使用 TypeScript。如果这不适合你的情况,你也会明白其中原因。Scott Meyers——《Effective C++》的作者,给出了一个难忘的例子。Scott 遇到了一个工程师团队,他们写的软件是在导弹上运行的。他们知道他们可以忽略Scott 关于防止资源泄漏的建议,因为当导弹击中目标,硬件爆炸时,他们的程序总是会终止的。我不知道有任何带有 JavaScript 运行时的导弹,但是 James Webb 太空望远镜是有的,所以你永远不会知道你的代码会在哪使用!
最后,每一个条款都以“要记住的事情”结束,其下是从该条款出发总结的几个要点。如果你只是浏览本书,你可以阅读这些,以了解该条款在讲什么,以及你是否想读更多。你还是应该读读这篇文章!但总结也是必要的。
TypeScript 示例代码约定
除非上下文清楚地表明它们采用的是 JSON、GraphQL 或其他某种语言,其余所有代码示例采用的都是 TypeScript 语言。使用TypeScript 的大部分经验都涉及与编辑器的交互,这给输出带来了一些挑战。我已经采用了一些惯例使得这个办法可行。
大多数编辑器都使用弯曲下划线来显示错误。若要查看完整的错误消息,需要将鼠标悬停在带下划线的文本上。为了指示代码示例中的错误,我在错误发生的位置下的注释中使用了波浪线标记:
let str = 'not a number';
let num: number = str;
// ~~~ Type 'string' is not assignable to type 'number'
为了简洁明了,我偶尔会编辑错误消息,但从不删除错误。如果将代码示例复制/ 粘贴到编辑器中,则应能准确地获得错误提示,且不多不少。
为了提示没有错误,我使用 //OK 标记:
let str = 'not a number';
let num: number = str as any; // OK
你应该能够将鼠标悬停在编辑器中的符号上,以查看 TypeScript 认为其类型是什么。为了在文本中指出这一点,我使用了以 “type is” 开头的注释标记:
let v = {str: 'hello', num: 42};
// Type is { str: string; num: number; }
该类型用于行上的第一个符号(在本例中为 v)或函数调用的结果:'four score'.split(' '); // Type is string[]
这与你在编辑器中看到的字符对字符的类型相匹配。在函数调用的情况下,可能需要分配临时变量以查看类型。
我偶尔会引入没有意义的语句来指示特定代码行上的变量类型:
function foo(x: string|string[]) {
if (Array.isArray(x)) {
x; // Type is string[]
} else {
x; // Type is string
}
}
x; 行仅用于演示条件的各个分支中的类型。你不需要(也不应该)在自己的代码中包含这样的语句。
除非上下文中另有说明或明确说明,否则代码示例将使用 strict 标志进行检查。所有示例均使用 TypeScript 3.7.0-beta 进行了验证。
排版约定
本书使用了下述排版约定:
斜体(Italic)
表示新术语、URL、电子邮件地址、文件名和扩展名。
等宽字体(Constant Width)
表示程序列表,以及段落中引用程序的元素,如变量或函数名、数据库、数据类型、环境变量、语句和关键字。
等宽粗体(Constant width bold)
表示用户应逐字输入的命令或其他文本。
等宽斜体(Constant width italic)
表示应替换为用户提供的值或由上下文确定的值的文本。
使用示例代码
补充材料(代码示例、练习等)可从 https://github.com/danvk/effectivetypescript下载。
如果你有技术问题或使用代码示例时遇到问题, 请发送电子邮件至bookquestions@oreilly.com
本书是来帮助你完成工作的。一般来说,如果本书提供了示例代码,你可以在程序和文档中使用它。你不需要联系我们获得许可,除非你正在复制代码的重要组成部分。例如,编写一个使用本书中几段代码的程序不需要获得许可,而销售或分发O’Reilly 书籍的示例是需要获得许可的;通过引用本书并引用示例代码来回答问题不需要获得许可,而将本书中大量的示例代码合并到产品文档中却是需要获得许可的。
我们不强制要求署名,但如果你这么做,我们深表感激。署名一般包括书名、作者、出版社和国际标准图书编号。例如,“Effective TypeScript by Dan Vanderkam (O’Reilly). Copyright 2020 Dan Vanderkam, 978-1-492-05374-3。”
如果你觉得自身情况不在合理使用或上述允许的范围内,请通过邮件和我们联系,地址是 permissions@oreilly.com
O’Reilly 在线学习平台(O’Reilly Online Learning)
近40 年来,O’Reilly Media 致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。
我们拥有独一无二的专家和革新者组成的庞大网络,他们通过图书、文章、会议和我们的在线学习平台分享他们的知识和经验。O’Reilly 的在线学习平台允许你按需访问现场培训课程、深入的学习路径、交互式编程环境,以及O’Reilly 和200 多家其他出版商提供的大量文本和视频资源。有关的更多信息,请访问http://oreilly.com
意见和疑问
请把你对本书的意见和疑问发给出版社:
美国:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司
本书有专属网页,你可以在那儿找到本书的勘误、示例和其他信息。这个网页的地址是 https://oreil.ly/Effective_TypeScript
如果你对本书有一些评论或技术上的建议, 请发送电子邮件到bookquestions@oreilly.com
有关我们的书籍、课程、会议和新闻的更多信息,请访问我们的网站:http://www.oreilly.com
我们的 Facebook : http://facebook.com/oreilly
我们的 Twitter : http://twitter.com/oreillymedia
我们的 YouTube: http://www.youtube.com/oreillymedia
致谢
许多人的帮助使本书的出版成为可能。感谢 Evan Martin 给我介绍TypeScript,并教我如何思考。感谢 Douwe Osinga 把我和 O’Reilly 联系起来并支持这个项目。感谢 Brett Slatkin 提供的结构方面的建议,让我认识到我是可以写一本 Effective 系列丛书的人。感谢 Scott Meyers 提出的这种格式,以及他的《高效的Effective 书籍》博客文章,这篇文章为我提供了必要的指导。感谢我的审校——Rick Battaglin、Ryan Cavanaugh、Boris Cherny、Yakov Fain、Jesse Hallett 和 Jason Killian,感谢所有在 Sidewalk 和我一起学习TypeScript 的同事,感谢在 O’Reilly 帮助本书得以实现的每一个人——Angela Rufino、Jennifer Pollock、Deborah Baker、Nick Adams 和 Jasmine Kwityn。感谢 TypeScript 的纽约团队成员——Jason、Orta、Kirill,以及所有的演讲者。许多条款的灵感皆来自会议上的会谈,如下所示:
• 条款 3 的灵感来自 Evan Martin 的一篇博客,在我第一次学习 TypeScript的时候,我就发现这篇文章特别有启发性。
• 条款 7 的灵感来自 Anders 在 2018 年 TSConf 大会上关于结构类型和keyof 关系的演讲,以及 Jesse Hallett 在 2019 年 4 月纽约 TypeScript 会议上的演讲。
• Basarat 的指南及 DeeV 和 Gpicazo 在 Stack Overflow 的回答对编写条款 9时都是必不可少的。
• 条款 10 建立在《Effective JavaScript》(Addison Wesley)的条款 4 中的类似建议之上。
• 在 2019 年 8 月的纽约 TypeScript 会议上,我被围绕额外类型检查的局限性这一话题所鼓舞,写下了条款11。
• 在 Stack Overflow 上关于“type”与“interface”的几个问题极大地帮助了条款13。Jesse Hallett 提出了关于可扩展性的公式。
• Jacob Baskin 为条款 14 提供了鼓励和早期反馈。
• 条款 19 的灵感来自提交给 Reddit TypeScript 话题的几个代码示例。
• 条款 26 是基于我自己在 Medium 上的文章和我在 2018 年 10 月纽约TypeScript 会议上的演讲。
• 条款 28 基于 Haskell 的一般建议(非法状态不能表示)。法航 447 的故事灵感来自 Jeff Wise 2011 年在《大众机械》上发表的文章。
• 条款 29 基于我在 Mapbox 类型声明中遇到的一个问题。Jason Killian 建议在标题中使用这个短语。
• 条款 36 关于“命名”的建议很常见,但是这个建议是受 Dan North 在《程序员应该知道的97 件事》(O’Reilly)的启发。
• 条款 37 的灵感来自 Jason Killian 在 2017 年 9 月纽约第一次 TypeScript 会议上的演讲。
• 条款 41 基于 TypeScript 2.1 release note。“any 演变”这个术语在TypeScript 编译器本身之外并没有被广泛使用,但是我发现为这个不寻常的模式命名是很有用的。
• 条款 42 的灵感来自 Jesse Hallett 的一篇文章。
• Titian Cernicova Dragomir 对 TypeScript issue #33128 提出的反馈对条款43 很有帮助。
• 条款 44 基于 York Yao 的“类型覆盖”工具所做的工作。我想要这样的一个工具并且它竟然存在!
• 条款 46 基于我在 2017 年 12 月纽约 TypeScript 会议上的演讲。
• 多亏了 David Sheldrick 在 “Artsy” 博客上发表的关于条件类型的文章,这让我对条款50 这个话题大开眼界。
• 条款 51 的灵感来自 Steve Faulkner 即 southpolesteve 在 2019 年 2 月的会议上的演讲。
• 条款 52 基于我自己在 Medium 上的文章和输入检查工具的工作,它最终被打包放入dtslint 里。
• 条款 53 的灵感来自 Kat Busch 在 Medium 上关于 TypeScript 中各种枚举类型的帖子,以及 Boris Cherny 在《Programming TypeScript》(O’Reilly)中关于这个主题的文章。
• 条款 54 的灵感来自我自己和同事在这个话题上的困惑。Anders 对TypeScript 的 PR#12253 给出了明确的解释。
• MDN 文档对于编写条款 55 非常重要。
• 条款 56 大致基于《Effective JavaScript》(Addison-Wesley)的条款 35。
• 第 8 章基于我自己迁移老化动态图库的经验。
我在 Reddit 的 TypeScript 专题下找到了很多优秀的博客文章和访谈,它们同样也帮助促成了本书。我特别感谢在那里提供代码示例的开发人员,这些示例对于帮助初学者理解 TypeScript 使用中面临的常见问题非常重要。感谢Marius Schulz 的每周 TypeScript newsletter。虽然它只是偶尔的每周,但它是一个很好的材料来源和跟上 TypeScript 很好的方式。感谢 Anders、Daniel、Ryan 和微软的整个 TypeScript 团队,他们与我进行会谈,并就问题提供所有反馈。我的大部分问题都是误会,但没有什么比提交一个错误并立即看到Anders Hejlsberg 自己修复它更有成就感的了!最后,感谢 Alex 在我完成整个项目的过程中,无时无刻对我的体谅。