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.

Advanced Types

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

  1. Prefer concrete types — Use interface{} only when the type truly varies. If you know the field is always an object, define a struct.
  2. Use json.RawMessage for deferred parsing — If the type depends on another field, unmarshal into json.RawMessage first, then decode conditionally.
  3. 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.

Try It — JSON to Go Struct Converter

Open full tool