An interface is best when multiple types truly share a stable shape or behaviour and you want to describe that common contract. A union type is better when the function must accept one of several distinct concrete types without pretending they are the same. For audit logging, the union preserves specificity while still enabling one shared implementation.
Why Interfaces and Union Types Solve Different Problems in Logging
An interface describes a shared contract, so it works best when every logged object is meant to expose the same stable fields. A union type models alternatives, so it fits when audit events come in distinct shapes and the logger must accept each one without flattening them into a false common shape. For logging, that difference matters because the type should reflect the real event structure, not just the implementation convenience.
With an interface, the compiler assumes the same property set is available across all values. That is useful when you want consistent fields such as timestamp, actor, action, and correlation ID across every record. If the data you log is truly uniform, an interface keeps the code readable and makes shared handling straightforward. If the records diverge materially, forcing them into one interface usually leads to optional properties that hide meaningful differences.
A union type keeps those differences explicit. The logger can accept one of several event shapes, then narrow on the fields that identify each shape. That is especially useful when the audit trail needs to preserve source-specific context, because the code can treat a payment event, a security event, and a configuration event as separate cases while still sending them through one pipeline. If you want to avoid losing detail, the union is the safer representation.
When a Logging Contract Should Stay Uniform, and When It Should Stay Specific
For a logging API, an interface is usually the better choice for the shared envelope around every event. That envelope might define metadata the platform always needs, such as event time, actor ID, severity, and request correlation. The event payload itself can still vary, but the outer contract stays stable so ingestion, storage, and search remain predictable.
A union type becomes more valuable when the payload is the point of the design. If the logger needs to handle several concrete event categories, each with its own required fields and business meaning, a union lets the type system preserve that distinction. In practice, that means you can keep type safety without pretending every event has the same payload shape. The result is often better exhaustiveness checking and fewer unsafe casts.
The trade-off is that unions often push you toward narrowing logic, which is appropriate when the implementation genuinely depends on the event kind. Interfaces reduce branching when the data is already harmonised. For that reason, the usual design pattern is not “interface versus union” at the top level, but “interface for the common envelope, union for the variant payloads.”
Choosing the Right Shape for Audit Logging Code
In audit logging, the design choice should follow the data contract you need to preserve. If every record really represents the same kind of event with the same meaningful fields, prefer an interface. If the system emits several distinct event families and you need to retain their differences for review, filtering, or downstream enrichment, prefer a union. The type should describe the audit reality, not force the events into a fake common model.
That distinction becomes important when logs are used for evidence, troubleshooting, or detection workflows. A shared interface is helpful when downstream systems expect uniform fields for indexing and correlation. A union is better when the semantic differences between events matter enough that hiding them would make analysis weaker or less trustworthy. In other words, consistency helps operations, while specificity helps fidelity.
Risk and Threat Considerations
Logging types matter because weak modelling can erase security-relevant detail. If you overuse a single interface and make important fields optional, it becomes easier to emit incomplete events that are hard to search, correlate, or trust during an incident. If you overcompress distinct event types into one shape, you can also lose the context needed to spot abuse patterns or prove what happened.
Failure mechanism: A poorly chosen interface encourages generic records and optional fields, which can blur event meaning, weaken validation, and create blind spots in downstream investigation or alerting.
Impact: Investigators may miss key distinctions between event classes, and automation may index or interpret the logs incorrectly, reducing both detection quality and evidential value.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP ASVS, NIST SP 800-53 Rev 5 and CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP ASVS | V16 — Security Logging and Error Handling | Logging type design affects event fidelity and auditability. |
| Recommendation — Model log events to preserve required fields and avoid ambiguous audit records. | ||
| NIST SP 800-53 Rev 5 | AU-2 — Event Logging | The question concerns structuring log events for audit use. |
| AU-3 — Content of Audit Records | Interface versus union determines whether records retain the needed event detail. | |
| Recommendation — Define which event types and fields must be captured in audit logs. Specify the fields each audit record must contain and keep variant details intact. | ||
| CIS Controls v8 | CIS-8 — Audit Log Management | The logging use case maps directly to preserving usable audit records. |
| Recommendation — Standardise log structure so audit data stays searchable, complete, and reviewable. | ||
Practitioner Guidance
What to verify: Check whether the events you are logging truly share one contract, or whether they only share a transport wrapper. If the inner data varies by event kind, keep that variation explicit in the type rather than hiding it behind optional properties.
Decision rule: Use an interface for the common audit envelope, and use a union for the payload variants when the logger must preserve the exact event category. If the code needs different handling paths for different cases, that is a strong sign that a union is the better fit.
Practitioner takeaway: The best type is the one that preserves the meaning of the log event with the least distortion, because audit logging is only useful when the structure in code matches the structure in reality.
Related resources from NHI Mgmt Group
- TypeScript
- Why is a union type often better than forcing a shared interface for audit logging and similar cross-entity workflows?
- How should teams use union types when several entities need the same handling but do not share a meaningful base interface?
- What breaks when TypeScript type information is lost at runtime in a union-based design?
Deepen Your Knowledge
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.
Bonus 33% off our NHI Course when you subscribe.
Reviewed and updated by the NHIMG editorial team on October 30, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org