以下の本より冒頭部分を自己整理。

O’Reilly Japan - プログラミング TypeScript

コンパイルプロセス

TypeScript に入る前に JavaScript のコンパイルプロセスは以下。通常のプログラミング言語と同様。

  1. JavaScript ソースコードを JavaScript の AST(抽象構文木)に変換する
  2. AST をバイトコードに変換する
  3. バイトコードがランタイムによって評価される(実行される)

書籍より補足

JavaScript のコンパイラとランタイムは、多くの場合、エンジンと呼ばれる1つのプログラムにまとめられています。プログラマーは、通常、このエンジンと対話することになります。V8(Node.js, Chrome, Opera の原動力となるエンジン)、SpiderMonkey(FireFox)、JSCore(Safari)、Chakra(Edge)などはこのようなエンジンであり、JavaScript をインタープリター型言語のように見せているのは、これらの働きによるものです。

TypeScript をコンパイルすると JavaScript が出力されるが、その過程で型チェックを行なっている。

  1. TypeScript ソースコードを TypeScript の AST に変換する
  2. AST が型チェッカー(typechecker)プログラムによってチェックされる
  3. AST を JavaScript ソースコードに変換する

上記の 1 と 2 のプロセスで型を使用するが、3 のプロセスに入ると TypeScript のコンパイラ(TSC)はもう型を見ない。つまりプログラマーが記載した型情報は 2 までで役割を終え、3 以降は利用されず、通常の JavaScript と同様になる。

型の階層構造

A の型の値が B の型に代入可能なとき、「A は B のサブタイプ」で「B は A のスーパータイプ」という関係にある。

TypeScript の型のスーパータイプ / サブタイプの関係は以下のようになっている。

Type hierarchy

unknown はすべての型のスーパータイプであり、never はすべての型のサブタイプである。

なおこういった場合、unknown のような存在をトップ型(top type)と呼び、never のような存在をボトム型(bottom type)と呼ぶ。

型の階層構造が上記のようになっているということは以下のように代入可能ということ。

const a: 'hello' = 'hello'; // String Enum type ('hello' type)
const b: string = a; // String type
const c: any = b; // Any type
const d: unknown = c; // Unknown type