(硬核干货)探索类型系统的底层 - 自己实现一个 TS

论坛 期权论坛     
选择匿名的用户   2021-5-30 00:12   243   0
<div id="js_content">
<p style="text-align: center">点击上方关注 前端技术江湖,一起学习,天天进步<br><br></p>
<p style="text-align: center"><img src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-6b507e9961f1e75c086fd3783838c206.png"></p>
<p style="text-align: left">原文:https://indepth.dev/under-the-hood-of-type-systems/,DawnL 译</p>
<p><br>这篇文章包含两个部分:<br></p>
<p><strong>A 部分:类型系统编译器概述(包括 TypeScript)</strong></p>
<ul><li><p>Syntax vs Semantics 语法 vs 语义</p></li><li><p>What is AST? 什么是 AST?</p></li><li><p>Types of compilers 编译器的类型</p></li><li><p>What does a language compiler do? 语言编译器是做什么的?</p></li><li><p>How does a language compiler work? 语言编译器是如何工作的?</p></li><li><p>Type system compiler jobs 类型系统编译器职责</p></li><li><p>Advanced type checker features 高级类型检查器的功能</p></li></ul>
<p><strong>B 部分:构建我们自己的类型系统编译器</strong></p>
<ul><li><p>The parser 解析器</p></li><li><p>The checker 检查器</p></li><li><p>Running our compiler 运行我们的编译器</p></li><li><p>What have we missed? 我们遗漏了什么?</p></li></ul>
<h1>A 部分:类型系统编译器概述</h1>
<h2>语法 vs 语义</h2>
<p>语法和语义之间的区别对于早期的运行很重要。</p>
<h3>语法 - Syntax</h3>
<p>语法通常是指 JavaScript 本机代码。本质上是询问给定的 JavaScript 代码在运行时是否正确。</p>
<p>例如,下面的语法是正确的:</p>
<pre class="blockcode"><code class="language-go">var foo: number &#61; &#34;not a number&#34;;
</code></pre>
<h3>语义 - Semantics</h3>
<p>这是特定于<strong>类型系统</strong>的代码。本质上是询问附加到代码中的<strong>给定类型</strong>是否正确。</p>
<p>例如,上面的代码在语法上是正确的,但在语义上是错误的(将变量定义为一个数字类型,但是值是一个字符串)。</p>
<p>接下来是 JavaScript 生态系统中的 AST 和编译器。</p>
<h2>什么是 AST?</h2>
<p>在进一步讨论之前,我们需要快速了解一下 JavaScript 编译器中的一个重要机制 AST。</p>
<p>关于 AST 详细介绍请看这篇文章。</p>
<p>AST 的意思是<strong>抽象语法树</strong> ,它是一个表示程序代码的<strong>节点</strong>树。<strong>Node</strong> 是最小单元,基本上是一个具有 <code>type</code> 和 <code>location</code> 属性的 POJO(即普通 JavaScript 对象)。所有节点都有这两个属性,但根据<strong>类型</strong>,它们也可以具有其他各种属性。</p>
<p>在 AST 格式中,代码非常容易操作,因此可以执行添加、删除甚至替换等操作。</p>
<p>例如下面这段代码:</p>
<pre class="blockcode"><code class="language-go">function add(number) {
  return number &#43; 1;
}
</code></pre>
<p>将解析成以下 AST:</p>
<img src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-84431ce24b74f2ac2569fdc69c7f78c0.png">
<h2>编译器类型</h2>
<p>在 JavaScript 生态系统中有两种主要的编译器类型:</p>
<h3>1. 原生编译器(Native compiler)</h3>
<p>原生编译器将代码转换为可由服务器或计算机运行的代码格式(即机器代码)。类似于 Java 生态系统中的编译器 - 将代码转换为字节码,然后将字节码转换为本机代码。</p>
<h3>2. 语言编译器</h3>
<p>语言编译器扮演着不同的角色。TypeScript 和 Flow 的编译器在将代码输出到 JavaScript 时都算作语言编译器。</p>
<p>语言编译器与原生编译器的主要区别在于,前者的编译目的是 <code>tooling-sake</code>(例如优化代码性能或添加附加功能),而不是为了生成机器代码。</p>
<h2>语言编译器是做什么的?</h2>
<p>在类型系统编译器中,总结的两个最基本的核心职责是:</p>
<h3>1. 执行类型检查</h3>
<p>引入<strong>类型</strong>(通常是通过显式注解或隐式推理),以及检查一种类型是否匹配另一种类型的方法,例如 <code>string</code> 和 <code>number</code>。</p>
<h3>2. 运行语言服务器</h3>
<p>对于一个在开发环境中工作的类型系统(type system)来说,最好能在 IDE 中运行任何类型检查,并为用户提供即时反馈。</p>
<p>语言服务器将类型系统连接到 IDE,它们可以在后台运行编译器,并在用户保存文件时重新运行。流行的语言,如 TypeScript 和 Flow 都包含一个语言服务器。</p>
<h3>3. 代码转换</h3>
<p>许多类型系统包含原生 JavaScript 不支持的代码(例如不支持类型注解) ,因此它们必须将不受支持的 JavaScript 转换为受支持的 JavaScript 代码。</p>
<p>关于代码转换更详细的介绍,可以参考原作者的这两篇文章 Web Bundler 和 Source Maps。</p>
<h2>语
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP