PHP中如何简洁声明嵌套对象接口?TypeScript接口转换场景
Great question! Let's break this down into your two core concerns: cleaner nested interface declarations in PHP, and whether anonymous interfaces exist (like you tried with that inline new interface syntax).
First: Can we write nested object interface declarations more concisely in PHP?
PHP doesn't natively support nesting interfaces inside other interfaces (unlike TypeScript's inline type definitions). But there are a few workarounds to avoid an explosion of top-level interfaces:
Option 1: Use DocBlock annotations for nested shapes
You can keep a single Tournament interface and use DocBlock syntax to describe the nested structure of the phases property. This works great for IDE type hints, even though it's not enforced at runtime:
/** * @property int $id * @property string $name * @property array{ * league: array{groups: int, twoLegged: bool}, * playoff: array{twoLegged: bool} * } $phases */ interface Tournament {}
This avoids creating separate Tournament_Phases, Tournament_Phase_League, etc. interfaces entirely, using array shape notation to define the nested structure.
Option 2: Organize interfaces with namespaces
If you still want strong interface contracts (not just hints), you can group related interfaces under a namespace to keep things clean, instead of using long prefixes like Tournament_Phases:
namespace Tournament; interface Tournament { public function getId(): int; public function getName(): string; public function getPhases(): Phases; } interface Phases { public function getLeague(): League; public function getPlayoff(): Playoff; } interface League { public function getGroups(): int; public function isTwoLegged(): bool; } interface Playoff { public function isTwoLegged(): bool; }
This keeps the global namespace uncluttered and makes the relationship between interfaces obvious.
Option 3: Use DTO Classes (for runtime type safety)
If you need actual runtime type enforcement instead of just interfaces, consider using Data Transfer Objects (DTOs) with PHP 8.0+ property types (and 8.2+ readonly for immutability). This is more practical for working with actual data:
readonly class Tournament { public function __construct( public int $id, public string $name, public TournamentPhases $phases, ) {} } readonly class TournamentPhases { public function __construct( public TournamentLeague $league, public TournamentPlayoff $playoff, ) {} } readonly class TournamentLeague { public function __construct( public int $groups, public bool $twoLegged, ) {} } readonly class TournamentPlayoff { public function __construct( public bool $twoLegged, ) {} }
While this still uses multiple classes, it gives you strict type checking at runtime and works seamlessly with PHP's type system.
Second: Does PHP support anonymous interfaces?
Short answer: No. PHP has anonymous classes (which can implement interfaces), but it does not allow defining anonymous interfaces themselves. The syntax you tried:
interface Tournament { public $phases = new interface { $league= new interface { $groups; $twoLegged; } $playoff = ...; } }
is invalid in PHP. Interfaces must have an explicit, named definition—you can't inline them as properties or values like you can with TypeScript's inline types.
Final Recommendation
- If you just need IDE type hints and want minimal code: Go with the DocBlock array shape approach.
- If you need formal interface contracts: Use namespaces to organize your interfaces cleanly.
- If you need runtime type safety: Use readonly DTO classes.
内容的提问来源于stack exchange,提问作者Javier Marín

