Haxe Structural Typing for Anonymous Objects: Shape Matching at Compile Time
Haxe accepts any object that matches a function’s required field shape at compile time, ignoring extra properties and rejecting missing required fields. Here’s how the matching works and what to watch out for.
26 Jul 2026, 16:33 UTC

You define a Haxe function that expects an object with specific fields, then pass a plain object literal. Whether it compiles depends on shape matching, not on whether the object was declared as a nominal type.
How Haxe Structural Matching Works
Haxe validates function parameters by the fields they require, not by the exact type of the argument. If a function expects {x: Int, y: Int}, any object containing those two fields—plus any number of additional fields—will compile without error.
function describePoint({x: Int, y: Int}) {
return "at ($x, $y)";
}
var obj = {x: 3, y: 7, label: "origin"};
describePoint(obj); // compiles: obj provides the required shape
If a required field is absent, the compiler stops with a type error pointing at the missing field:
var incomplete = {x: 3};
describePoint(incomplete); // error: field y is missing
Optional Fields and the ? Syntax
To make a field optional in the structural type, append ? to its type in the function signature. Omitting the field then causes no error, and the parameter receives a null or undefined value depending on target.
function greet({name: String, nickname?: String}) {
return "Hello, " + (nickname ?? name);
}
greet({name: "Alice"}); // compiles and runs
greet({name: "Bob", nickname: "Rob"}); // compiles and runs
Targets and Runtimes
When Haxe compiles to JavaScript, the structural checks disappear. The generated code contains no runtime shape validation; the compiler’s matching is entirely a compile‑time concern. This means dynamically typed JavaScript code can bypass the compile‑time guarantees entirely.
Common Mistakes
- Expecting runtime checks. Structural matching is compile-only; JavaScript code produced from Haxe will not enforce the shape at runtime.
- Forgetting the
?suffix. A field declared asString(without?) is required; its absence is a compile error. - Relying on structural types for API documentation. Explicit type aliases or interfaces better communicate intent than inferred shapes.
- Unintended matches across modules. If two unrelated objects happen to share the same field names and types, Haxe’s structural matching will accept one for the other, reducing intended type safety.
Verification Checklist
- Create a Haxe function that accepts a structural type with required fields.
- Pass an object containing those required fields plus extras; confirm the compiler accepts the call.
- Omit one required field from the passed object and verify the compiler reports a type error indicating the missing field name.
- Compile the same code targeting JavaScript and inspect the generated output to confirm no runtime shape validation is inserted.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.