R25BREAKINGinterface

Interface Property Required

Flags when a new required property is added to an interface, or an existing optional property becomes required. All implementations must now provide the new field.


Applies to

TypeScriptJavaGoRust

Why it matters

Adding a required property to an interface means every object literal, class implementation, or struct that conforms to the interface must now include the new field. This can affect dozens of files.

Example

Before
// types.ts
export interface UserConfig {
  name: string;
  theme?: string;
}

// implementations
const config: UserConfig = { name: "Alice" }; // valid
After (new required property)
// types.ts (BREAKING)
export interface UserConfig {
  name: string;
  theme?: string;
  email: string;  // NEW required property
}

// implementations — NOW BROKEN
const config: UserConfig = { name: "Alice" };
// ERROR: Property 'email' is missing

What you see in the terminal

$ npx dg check

  [BREAKING] UserConfig (interface_property_added)
  src/types.ts:2
  A new required property 'email' was added to the interface. Consumers must update their objects.

How detection works

The classifier iterates through the new interface's properties. For each required property (not optional), it checks: 1. If the property is completely new (didn't exist in old) — that's a new required field. 2. If the property existed in old but was optional and is now required — that's a tightened constraint.

Real-world scenario

A configuration interface gains a required `email` field for notification support. Every place that creates a UserConfig object — tests, seed data, factories — needs to add the email field.

Edge cases

  • Adding an optional property (?) is not caught by this rule — that's safe
  • Changing optional to required (theme?: string -> theme: string) is caught
  • In Go, adding a required struct field is equivalent