Excess Property Checks in TypeScript

Excess property checks catch unknown properties on object literals passed directly to typed positions. Learn when this check fires, when it does not, and how to handle it correctly.

5 min read

TypeScript excess property checks are a special rule applied to object literals. When you pass an object literal directly to a typed variable or function, TypeScript rejects any property that is not declared in the target type, even if all required properties are present.

This is not the same as structural typing. Under normal structural typing, an object with extra properties is fine. The excess property check is an additional, stricter rule reserved for object literals.

Why the check exists

In plain JavaScript, if you pass an object with a misspelled property to a function, nothing happens. The misspelled property sits on the object, the real property is undefined, and the bug goes unnoticed until it causes a crash somewhere else.

TypeScript catches this with excess property checking.

typescripttypescript
interface SquareConfig { color?: string; width?: number; }
 
function createSquare(cfg: SquareConfig) {
  return { color: cfg.color ?? "red", area: (cfg.width ?? 10) ** 2 };
}
 
createSquare({ colour: "red", width: 100 });
// Error: Object literal may only specify known properties, and
// 'colour' does not exist in type 'SquareConfig'. Did you mean to write 'color'?

The error points directly at the misspelling. When the property name is close to a real one, TypeScript also suggests the correct spelling.

When the check fires

The excess property check only applies to object literals. An object literal is an object you write inline at the point of assignment or argument passing. If you assign the object to a variable first, the check is skipped.

typescripttypescript
const options = { colour: "red", width: 100 };
createSquare(options); // OK -- no excess property check

The variable options has the inferred type { colour: string; width: number }. When you pass it to createSquare, structural typing takes over: the object has at least the required width property, and the extra colour is harmless.

This is by design. TypeScript assumes that if you went to the trouble of naming a variable, you might be using those extra properties somewhere else. The literal check is only for inline objects that are likely to be one-shot, and therefore more likely to contain typos.

How to handle excess property errors

When you get an excess property error, your first move should be to check for a typo. Most of the time, the error is correct and there is a bug.

If the extra property is genuinely intentional, you have three options.

Add an index signature to the type. This tells TypeScript the type accepts any additional properties beyond the ones you explicitly declared:

typescripttypescript
interface SquareConfig {
  color?: string;
  width?: number;
  [key: string]: unknown;
}

Now any extra property is accepted, regardless of name or type.

Use a type assertion to tell TypeScript you know what you are doing:

typescripttypescript
createSquare({ colour: "red", width: 100 } as SquareConfig);

The as SquareConfig overrides the excess property check. Use this sparingly -- it silences the check, so you lose its protection against real typos.

Assign the object to an intermediate variable. This is the simplest approach and works because excess property checking only targets object literals. However, if the variable has no properties in common with the target type, TypeScript still reports an error because the types have no overlap.

Common mistakes

Assuming excess property checks are a bug in TypeScript. They are a deliberate safety net. If you keep hitting them, check your property names before reaching for a workaround.

Using type assertions to silence every excess property error. Assertions bypass the check entirely. If you later introduce a real typo, you will not catch it. Use assertions only when you are certain the extra property is intentional.

Confusing excess property checks with structural typing. Structural typing says an object can have more properties than the type requires. Excess property checking is an extra rule for object literals only. They serve different purposes and apply in different situations.

For more on how object types work, see object types in TypeScript and index signatures in TypeScript.

Rune AI

Rune AI

Key Insights

  • Excess property checks only apply to object literals, not to intermediate variables.
  • The check catches typos in property names that would silently fail in plain JavaScript.
  • You can bypass the check with a type assertion, an index signature, or by assigning to a variable first.
  • Most excess property errors are real bugs -- fix the typo before using a workaround.
  • The check has nothing to do with structural typing; extra properties are normally allowed.
RunePowered by Rune AI

Frequently Asked Questions

Why does TypeScript allow extra properties sometimes but not always?

TypeScript only checks for excess properties on object literals assigned directly to a typed position. When you assign to an intermediate variable first, the check is skipped because the variable has a wider inferred type that may include the extra properties intentionally.

How do I fix an excess property check error?

The best fix is to correct the typo or spelling error that triggered it. If the extra property is intentional, you can add an index signature to the type, use a type assertion, or assign the object to an intermediate variable first.

Does excess property checking happen at runtime?

No. Like all TypeScript type checks, excess property checking happens only at compile time. At runtime, the extra properties exist in the object just like any other property in plain JavaScript.

Conclusion

Excess property checks are a special rule that TypeScript applies to object literals. They catch typos and unknown properties that would silently do nothing in plain JavaScript. When you encounter an excess property error, treat it as a real bug first -- check for typos before reaching for workarounds.