mcpField
E
excess-property-checking

excess-property-checking

github.com/marius-townhouse開発645 回インストール39 週間前に更新
リポジトリ

excess-property-checking について

余剰プロパティチェックと通常の型チェックの違いを解説する TypeScript 学習スキルです。オブジェクトリテラルのエラーやプロパティ名の誤記を理解し、安全でない回避を避けるのに役立ちます。

主な機能

  1. 01オブジェクトリテラルへのチェックを解説
  2. 02変数経由の代入との違いを比較
  3. 03型アサーションによる回避を説明
  4. 04オプション項目の誤記検出を紹介
  5. 05弱い型へのチェックを解説

活用シーン

  1. 01余剰プロパティのエラー差の調査
  2. 02オプション設定項目名の確認
  3. 03インデックスシグネチャの適否の判断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/marius-townhouse/effective-typescript-skills --skill excess-property-checking

インストール後、Claude Code で/excess-property-checkingを入力して読み込まれたか確認します。

詳細

余分なプロパティチェックと型チェックの違い

概要

オブジェクトリテラルは特別に扱われ、TypeScript は未知のプロパティを検出します。

これにより、構造的型付けでは見逃されるタイプミスや間違いを検出できます。ただし、これはオブジェクトリテラルにのみ適用されます。この違いを理解しておくと、混乱を避けられます。

このスキルを使う場面

  • オブジェクトリテラルを型付き変数に代入する場合
  • 余分なプロパティがエラーになる場合とならない場合がある理由が分からない場合
  • 中間変数を使うとエラーが消える場合
  • タイプミスが起こりやすいオプショナルプロパティを扱う場合
  • オプショナルフィールドの多いインターフェースを設計する場合

絶対に守るルール

ALWAYS remember: Excess property checking only applies to OBJECT LITERALS.

覚えておきましょう:

  • オブジェクトリテラル → 余分なプロパティが検出される
  • 変数の代入 → 構造的型付けが適用される
  • 型アサーション → 余分なプロパティチェックを回避する

検出:「余分なプロパティ」エラー

「Object literal may only specify known properties」というメッセージが表示された場合、余分なプロパティチェックが行われています。

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

// Excess property checking: Error!
const r: Room = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: 'present',
  // ~~~~~~~ Object literal may only specify known properties,
  //         and 'elephant' does not exist in type 'Room'
};

// Same value via intermediate variable: No error!
const obj = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: 'present',
};
const r2: Room = obj;  // OK - structural typing allows this

余分なプロパティチェックが存在する理由

構造的型付けは強力ですが、許容範囲が広い仕組みです。余分なプロパティを許すため、バグが隠れてしまうことがあります。

interface Options {
  title: string;
  darkMode?: boolean;
}

function createWindow(options: Options) {
  if (options.darkMode) {
    setDarkMode();
  }
}

// Without excess property checking, this typo would be silent:
createWindow({
  title: 'Spider Solitaire',
  darkmode: true  // lowercase 'm' - TYPO!
  // ~~~~~~~ Object literal may only specify known properties,
  //         but 'darkmode' does not exist in type 'Options'.
  //         Did you mean to write 'darkMode'?
});

余分なプロパティチェックが適用される場面

コンテキスト余分なプロパティチェック
オブジェクトリテラルを型付き変数に代入するはい
オブジェクトリテラルを関数の引数として渡すはい
オブジェクトリテラルを戻り値として返すはい
変数を型付き変数に代入するいいえ
型アサーションいいえ
interface Point { x: number; y: number; }

// Object literal - checking applies
const p1: Point = { x: 1, y: 2, z: 3 };  // Error: 'z' not in Point

// Variable - checking does NOT apply
const temp = { x: 1, y: 2, z: 3 };
const p2: Point = temp;  // OK

// Type assertion - checking does NOT apply
const p3 = { x: 1, y: 2, z: 3 } as Point;  // OK (but bad practice)

余分なプロパティチェックが役立つ場面

オプショナルプロパティのタイプミスを検出する
interface Config {
  logLevel?: 'debug' | 'info' | 'warn' | 'error';
  timeout?: number;
  retries?: number;
}

const config: Config = {
  loglevel: 'debug',  // Error: Did you mean 'logLevel'?
  timeout: 5000,
};
間違ったプロパティ名を防ぐ
interface User {
  firstName: string;
  lastName: string;
}

const user: User = {
  first_name: 'John',  // Error: Did you mean 'firstName'?
  last_name: 'Doe',    // Error: Did you mean 'lastName'?
};

余分なプロパティチェックを回避する(意図的な場合)

既知の余分なプロパティにはインデックスシグネチャを使う
interface Options {
  darkMode?: boolean;
  [otherOptions: string]: unknown;
}

const o: Options = { darkmode: true };  // OK now
中間変数を使う
const options = { title: 'Game', extraProp: true };
createWindow(options);  // OK - excess checking skipped

弱い型:関連するチェック

「弱い」型にはオプショナルプロパティしかありません。TypeScript は特別なチェックを追加します。

interface LineChartOptions {
  logscale?: boolean;
  invertedYAxis?: boolean;
  areaChart?: boolean;
}

const opts = { logScale: true };  // Note: capital 'S'
setOptions(opts);
// ~~~~ Type '{ logScale: boolean; }' has no properties in common
//      with type 'LineChartOptions'

このチェックは、通常の余分なプロパティチェックとは異なり、中間変数を介した場合にも適用されます。

よくある間違い

間違い 1:構造的型付けでタイプミスを検出できると思い込む
// ❌ Typo passes silently because no excess property checking
const options = { darkmode: true };  // lowercase 'm'
const config: Options = options;     // No error!

// ✅ Use object literal for catching typos
const config: Options = { darkmode: true };  // Error caught!
間違い 2:エラーを黙らせるために型アサーションを使う
// ❌ Assertion bypasses the check
const config = { darkmode: true } as Options;

// ✅ Fix the typo instead
const config: Options = { darkMode: true };
間違い 3:エラーが消える理由について混乱する
// This has an error
const p: Point = { x: 1, y: 2, z: 3 };

// Why doesn't this?
const temp = { x: 1, y: 2, z: 3 };
const p: Point = temp;

// Answer: Excess property checking only applies to object literals!

圧力に負けないためのプロトコル

1. 「as Typeを追加すればいい」

圧力:「型アサーションを使えばエラーが消えます」

**回答:**アサーションは安全性チェックを回避します。実際の問題を修正しましょう。

**対応:**プロパティ名を正すか、型定義を更新します。

2. 「TypeScript は厳しすぎる」

圧力:「余分なプロパティは問題にならないはずです」

**回答:**これにより、オプショナルフィールドのタイプミスなど、実際のバグを検出できます。

**対応:**本当に余分なプロパティが必要な場合は、インデックスシグネチャを使います。

3. 「変数を使えばうまくいく」

圧力:「エラーを避けるために中間変数を使えばいい」

**回答:**それではバグが隠れてしまいます。このエラーには理由があります。

**対応:**余分なプロパティが存在する理由を調べます。

危険信号 — いったん止まって再検討する

  • 余分なプロパティエラーを黙らせるために型アサーションを使っている
  • チェックを回避するためだけに中間変数を作っている
  • 代入によってエラーになる場合とならない場合がある理由が分からない
  • 余分なプロパティに対する TypeScript の挙動に一貫性がないと思っている

よくある正当化(すべて不適切)

言い訳実際のところ
「余分なプロパティがあるだけです」余分なプロパティは、多くの場合タイプミスを示しています
「構造的型付けなら許されます」オブジェクトリテラルには、正当な理由からより厳しいルールが適用されます
「アサーションで直ります」アサーションはバグを隠すだけで、修正はしません

クイックリファレンス

ケース余分なプロパティチェック例
オブジェクトリテラルを型付き変数に代入はいconst x: T = { ... }
オブジェクトリテラルを引数として渡すはいfn({ ... })
変数を型付き変数に代入いいえconst temp = {...}; const x: T = temp;
型アサーションいいえ{ ... } as T
弱い型(変数経由)共通するプロパティをチェック特殊なケース

要点

余剰プロパティチェックは、構造的型付けでは見逃されるバグを検出します。

このチェックはオブジェクトリテラルにのみ適用され、変数には適用されません。これは意図的な仕様です。特にオプショナルプロパティの名前の入力ミスを検出できます。型アサーションや中間変数で回避するのではなく、根本的な問題を修正してください。

参考資料

Dan Vanderkam 著『Effective TypeScript』項目 11「余剰プロパティチェックと型チェックを区別する」に基づいています。

コメント