TypeScript でオブジェクトリテラルに余分なプロパティを指定できない
「Object literal may only specify known properties」はオブジェクトリテラルに対する厳密チェック。
一度変数に代入する、型を拡張する、または index signature を加えると解消する。
#excess-property#type#object-literal#narrowing
公開:
要約
「Object literal may only specify known properties, and 'foo' does not exist in type 'Bar'」は TypeScript のオブジェクトリテラルに対する excess property check によるエラー。
リテラルを直接渡すと型に無いプロパティが拒否されるが、変数経由で渡すか型を広げれば回避できる。
よくある原因
- オブジェクトリテラル直渡し: TypeScript はリテラル経由の場合に限り、未定義プロパティを誤入力とみなして拒否する。
- 受け取り型が完全一致を要求: 関数引数や変数の型が optional プロパティを許しておらず、追加プロパティが想定されていない。
- タイポ:
colourとcolorのような単純な綴り間違いで、TypeScript が親切にエラーを出している。 - 型の更新漏れ: 実装側で増やしたプロパティを型定義に反映し忘れている。
解決策
1. 一度変数に入れる
excess property check は オブジェクトリテラルの直渡しのみ に効く。
変数に入れてから渡すと構造的部分型のチェックに切り替わり、追加プロパティが許される。
type Props = { name: string };
declare function render(p: Props): void;
// NG: excess property check
render({ name: "a", extra: 1 });
// OK: 変数経由
const obj = { name: "a", extra: 1 };
render(obj);ただし「タイポをすり抜ける」副作用もあるため安易に使わない(公式ドキュメント)。
2. 型に optional / index signature を追加する
将来的に拡張可能にしたい場合は型側を広げる。
type Props = {
name: string;
extra?: number; // 任意プロパティを明示
};
type Loose = {
name: string;
[key: string]: unknown; // 任意キーを許可
};[key: string]: T の index signature を入れると任意のキーを受け付けるようになる。
3. typo を直す
colour を color にするだけで解消するケースが意外と多い。
エラーメッセージ末尾の Did you mean 'color'? を信用する。
4. 最後の手段としての as
どうしても通す必要があるなら as で抑えるが、型安全性が崩れるので避ける。
render({ name: "a", extra: 1 } as Props);ライブラリ側の型定義が古いだけなら、declare module で型を上書きするほうが安全。