Mixed-Type JSON Fields as interface{} in Go
Handle JSON fields that contain different types across responses using Go interface{} (any). Learn type switches, assertions, and safe handling patterns.
Detailed Explanation
Handling Mixed-Type JSON Fields
Some JSON APIs return fields that can be different types depending on context — a field might be a string in one response and an object in another. Go handles this with interface{} (aliased as any since Go 1.18).
Example JSON
{
"result": "success",
"data": { "count": 42 },
"meta": [1, "two", true]
}
Here, result is a string, data is an object, and meta is a mixed array.
Generated Go Struct
type Response struct {
Result string `json:"result"`
Data interface{} `json:"data"`
Meta []interface{} `json:"meta"`
}
Type Switch Pattern
The idiomatic way to handle interface{} values is a type switch:
switch v := response.Data.(type) {
case map[string]interface{}:
fmt.Println("Object with keys:", len(v))
case string:
fmt.Println("String value:", v)
case float64:
fmt.Println("Number:", v)
case nil:
fmt.Println("Null value")
}
JSON's Default Type Mapping
When unmarshaling into interface{}, Go uses these defaults:
- JSON object →
map[string]interface{} - JSON array →
[]interface{} - JSON string →
string - JSON number →
float64(always, even for integers) - JSON boolean →
bool - JSON null →
nil
Best Practices
- Prefer concrete types — Use
interface{}only when the type truly varies. If you know the field is always an object, define a struct. - Use json.RawMessage for deferred parsing — If the type depends on another field, unmarshal into
json.RawMessagefirst, then decode conditionally. - Document the variants — Add comments explaining what types the field can hold.
type Event struct {
Type string `json:"type"`
Payload json.RawMessage `json:"payload"`
}
Then switch on Type to unmarshal Payload into the correct struct.
Use Case
Webhook systems like Stripe and GitHub send events where the payload type varies by event name. Using interface{} or json.RawMessage lets you handle polymorphic JSON payloads in a type-safe way.