I have constructed a small example of what I am trying to do:
type Service interface {
    Transform()
}
type XYZ struct {
    ID string `json:"id"`
}
func (s XYZ) Transform() {}
func main() {
    x := "could be anything"
    msg := []byte(`{"id": "123"}`)
    var msgS Service
    switch x {
    case "could be anything":
        msgS = XYZ{}
        break
    case "could be something else":
        // another type that implements Transform()
        break
    }
    err := json.Unmarshal(msg, &msgS)
    if err != nil {
        fmt.Println(err)
    }
    // msgS.Transform()
}
This returns an error:
json: cannot unmarshal object into Go value of type main.Service
Essentially, I need to be flexible with whatever x might hold, hence the switch. If I instantitate msgSto the actual type that implements Transform(), all works as expected.
I realise I might need to reconsider my whole implementation - Any ideas would be welcome!