TL;DR

  • TypeScript のシンボルは、型空間と値空間のどちらかに属する。型空間のコードは JavaScript に変換すると消える。
  • class や enum のように両方の空間に導入される構文や、typeof のように空間によって意味が変わる構文がある。

内容

型空間と値空間

型空間のコードは JavaScript のコードには残らないので(型消去)、TS Playground で生成される JavaScript を確認すると、型空間と値空間を見分ける直感を養える。

すべての値には静的な型があるが、型には型空間からしかアクセスできない。type や interface のような型空間の構文は、変換時に消える。

一方、class や enum のように、型と値の両方を導入する構文もある(enum はなるべく使わない:項目72)。次の例では、Cylinder を値として instanceof に使い、その結果 shape の型が Cylinder に絞り込まれる。

class Cylinder {
  radius: number
  height: number
 
  constructor(radius: number, height: number) {
    this.radius = radius
    this.height = height
  }
}
 
function calcVolume(shape: unknown) {
  if (shape instanceof Cylinder) {
    shape // shape: Cylinder
    shape.radius // shape.radius: number
  }
}

空間によって意味が変わる構文

次の構文は、型空間と値空間で意味が変わる。

構文値空間型空間
typeof実行時の型を表す文字列を返す値を受け取り、TypeScript の型を返す
[]obj['field'] と obj.field のどちらでもプロパティを参照できるPerson['first'] のようにブラケット記法を使い、中に型を入れる
thisJavaScript の thisメソッドの戻り値で自身を指す this 型
&、\|ビット AND とビット ORインターセクション型とユニオン型
const新しい変数を宣言するas const で、リテラルやリテラル式の推論される型を変える
extendsサブクラスを定義するサブタイプやジェネリック型の制約を定義する
infor (key in object) のループマップ型
!論理 NOT 演算子非 null アサーション

値空間の typeof が返すのは、'string'、'number'、'boolean'、'undefined'、'object'、'function'、'symbol'、'bigint' のどれかで、TypeScript の型とは異なる。

型空間の [] には型を入れるので、ユニオン型や number も使える。

const first: Person["first"] = jane["first"]
 
type PersonEl = Person["first" | "last"]
 
type Tuple = [string, number, Date]
type TupleEl = Tuple[number]

値空間の this についてはJavaScript の this(項目69)を参照する。型空間の this 型(polymorphic this type)は、サブクラスでメソッドチェーンを実装するときに便利である。そのほか、as const は項目20、マップ型は項目15、非 null アサーションは項目9で扱う。

キーワード