excess property check とは何か(ざっくりイメージ)
excess property check(余剰プロパティチェック)は、「その型に存在しないプロパティを、オブジェクトリテラルに書いていないか」を特別に厳しくチェックする仕組みです。
type Person = {
name: string;
age: number;
};
const p: Person = {
name: "Taro",
age: 20,
gender: "male", // ← Person にないプロパティ
};
// Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
TypeScriptPerson 型には gender が定義されていないので、
TypeScript は「そのプロパティ余計じゃない?」とコンパイルエラーにしてくれます。
ポイントは、「オブジェクトリテラルを直接代入しているときだけ、特別に厳しく見る」というところです。
どんなときに excess property check が働くのか
「オブジェクトリテラルを直接、型付きの変数や引数に渡したとき」
典型的なパターンはこれです。
type Person = {
name: string;
age: number;
};
let onlyX: Person;
onlyX = { name: "Taro", age: 20 }; // OK
onlyX = { name: "Taro", age: 20, gender: "male" };
// コンパイルエラー(余剰プロパティチェックが発動)
TypeScriptここで TypeScript は、
「Person にない gender が書かれている → それはたぶんミスだろう」と判断して止めます。
同じことは関数引数でも起こります。
type User = { name: string };
function saveUser(user: User) {}
saveUser({ name: "John" }); // OK
saveUser({ name: "John", age: 30 });
// Object literal may only specify known properties...
TypeScript「オブジェクトリテラルをその場で書いている」+「代入先の型がはっきりしている」
この組み合わせのときに、余剰プロパティチェックが発動します。
なぜこんなチェックがあるのか(TypeScript が守りたいもの)
「スペルミスや余計な値を、早めに検出したい」
たとえば、こういうコードを考えます。
type SquareConfig = {
color: string;
size: number;
};
const config: SquareConfig = {
color: "red",
size: 10,
colro: "blue", // スペルミス
};
TypeScriptJavaScript なら、colro は単に無視されるだけで、
「本当は color と書きたかったのに…」というバグに気づきにくくなります。
TypeScript はここで、
SquareConfigにcolroなんてプロパティはない- それはたぶん「余計なプロパティ」か「スペルミス」だ
と判断して、コンパイルエラーにしてくれます。
「型にないプロパティがオブジェクトリテラルに紛れ込んでいるのは、たいていバグだろう」
この前提に基づいて、あえて厳しくチェックしているわけです。
「変数を一度挟む」とエラーが出なくなる理由
直接リテラルのときだけ特別に厳しい
ここが一番ハマりポイントです。
type Person = {
name: string;
age: number;
};
const daniel = {
name: "Daniel",
age: 30,
gender: "male",
};
const danielAsPerson: Person = daniel; // これは OK [nakita628.github.io](https://nakita628.github.io/blog/posts/2025/11/21)
TypeScriptさっきと違って、gender があってもエラーになりません。
なぜかというと、余剰プロパティチェックは
「オブジェクトリテラルを直接代入しているときだけ」働くからです。
const p: Person = { ... }→ オブジェクトリテラルを直接代入 → チェック発動const tmp = { ... }; const p: Person = tmp;→ 既にあるオブジェクトを代入 → チェックしない
TypeScript は、「既にどこかで作られたオブジェクト」を受け取る場面では、
「余計なプロパティがあっても許容する」設計になっています。
これは、「構造的型システム」とのバランスを取るためです。
「必要なプロパティさえ揃っていれば、それ以外があっても受け取れる」柔軟さを残すために、
「リテラルのときだけ特別に厳しくする」という折衷案になっているわけです。
実務でどう意識すればいいか
「その場で書いたオブジェクトは、型と完全に一致しているか」を常に見られている
type User = { name: string };
function putStorage(user: User) {
window.sessionStorage.setItem("user", JSON.stringify(user));
}
const john = { name: "John", age: 30 };
putStorage(john); // これはエラーにならない [Qiita](https://qiita.com/interharuki/items/659baa44c66d48e72eb0)
TypeScriptこの例では、john に age があってもエラーになりません。
なぜなら、putStorage に渡しているのは「変数 john」であって、
オブジェクトリテラルを直接書いているわけではないからです。
もし「ここでは余計なプロパティを絶対に許したくない」と思うなら、
呼び出し側をこう書くと、余剰プロパティチェックが働きます。
putStorage({ name: "John", age: 30 }); // エラー(余剰プロパティチェック発動)
TypeScript「その場で { ... } と書いたときは、型と完全に一致しているか厳しく見られる」
この感覚を持っておくと、「なぜここではエラーで、あっちではエラーじゃないの?」というモヤモヤがかなり減ります。
初心者がまず掴んでおきたい excess property check の感覚
大事なポイントだけ、整理しておきます。
1. 何をしている機能か
「型にないプロパティを、オブジェクトリテラルに書いていないか」をチェックする機能です。
スペルミスや余計な値を、コンパイル時にあぶり出すための安全装置だと思ってください。
2. いつ働くか
「オブジェクトリテラルを直接、型付きの変数や引数に渡したとき」だけです。
一度変数に入れてから渡すと、このチェックは働きません。
3. どう付き合えばいいか
- 「その場で
{ ... }と書くときは、型と完全に一致させる」 - 「余計なプロパティを持つオブジェクトを許容したいなら、変数を挟む or 型側にインデックスシグネチャなどを検討する」
そして何より、エラーメッセージの
Object literal may only specify known properties, and ‘xxx’ does not exist in type ‘YYY’.
を見たら、
「あ、型にないプロパティを書いてるって教えてくれてるんだな」
と一度立ち止まって、「それは本当に必要なプロパティか?スペルミスでは?」と自分に問い直してみてほしい。
その小さな確認の積み重ねが、
「意図しないデータが紛れ込んだまま本番に行く」みたいな事故を、かなりの確率で防いでくれます。

