メインコンテンツまでスキップ

余剰プロパティチェック (excess property checking)

TypeScriptのオブジェクトの型には余剰プロパティチェック(excess property checking)という、追加のチェックが働く場合があります。余剰プロパティチェックとは、オブジェクトの型に存在しないプロパティを持つオブジェクトの代入を禁止する検査です。

たとえば、{ x: number }はプロパティxが必須なオブジェクトの型です。この型に{ x: 1, y: 2 }のような値を代入しようとします。この代入は許可されるでしょうか。代入値の型は、必須プロパティの{ x: number }を満たしているので問題なさそうです。ところが、この代入は許可されません。

ts
let onlyX: { x: number };
onlyX = { x: 1 }; // OK
onlyX = { x: 1, y: 2 }; // コンパイルエラー
Type '{ x: number; y: number; }' is not assignable to type '{ x: number; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.2322Type '{ x: number; y: number; }' is not assignable to type '{ x: number; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
ts
let onlyX: { x: number };
onlyX = { x: 1 }; // OK
onlyX = { x: 1, y: 2 }; // コンパイルエラー
Type '{ x: number; y: number; }' is not assignable to type '{ x: number; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.2322Type '{ x: number; y: number; }' is not assignable to type '{ x: number; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.

このとき、「Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.」というコンパイルエラーが発生します。なぜこれがコンパイルエラーになるかというと、{ y: 2 }が余計だと判断されるからです。こうした余計なプロパティを許さないTypeScriptのチェックが余剰プロパティチェックなのです。

余剰プロパティチェックはオブジェクトリテラルだけを検査する

余剰プロパティチェックはオブジェクトの余計なプロパティを禁止するため、コードが型に厳密になるよう手助けをします。しかし、余剰プロパティチェックが効くのは、オブジェクトリテラルの代入に対してのみです。なので、変数代入にはこのチェックは働きません。

ts
const xy: { x: number; y: number } = { x: 1, y: 2 };
let onlyX: { x: number };
onlyX = xy; // OK
ts
const xy: { x: number; y: number } = { x: 1, y: 2 };
let onlyX: { x: number };
onlyX = xy; // OK

変数代入にも余剰プロパティチェックが働いたほうが良さそうと思われるかもしれません。型が厳密になるからです。しかし、そうなっていないのは、TypeScriptが型の安全性よりも利便性を優先しているためです。