将接口{}强制转换为运行时类型

Here is schematic example what I need:

func decode(data []byte, target interface{}) (interface{}, error) {
    decoded := target.(reflect.TypeOf(target)) // pseudocode
    err := json.Unmarshal(data, &decoded)
    ...

I found several similar questions on SO, but all solutions are about switch by target.(type). This is not the best solution what I look for.

Also I found solution with reflection:

decoded := reflect.ValueOf(target).Convert(reflect.TypeOf(target))
// fmt.Printf("%T", decoded) == reflect.Value

But I couldn't understand how to get struct from reflect.Value to pass it to json.Unmarshal function.

How this decode function will be used?

I have multiple requests in different structures. I can determine what struct I should use to decode request. I have mapping between request type and structure like this map[RequestMethod]interface{}.

Schematic version looks like this:

func hydrate(data []byte) (interface{}, error) {
    var base baseResponse

    if err := json.Unmarshal(data, &base); err != nil {
        return nil, err
    }

    target, ok := methodsMap[Method(base.Method)]

    if !ok {
        return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
    }

    decoded, err := decode(data, target) // Expected target type.

Added:

If we pass our target to json.Unmarshal without casting to it type we will obtain map. Example:

func decode(data []byte, target interface{}) (interface{}, error) {
    err := json.Unmarshal(data, &target)
    // fmt.Printf("%T", target) == map[string]interface{} not struct.

Solution

Thanks to @icza we found solution:

func hydrate(data []byte) (interface{}, error) { var base baseResponse

    if err := json.Unmarshal(data, &base); err != nil {
        return nil, err
    }

    target, ok := methodsMap[Method(base.Method)]

    if !ok {
        return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
    }

    // Clone request draft struct.
    decoded := reflect.New(reflect.ValueOf(target).Type()).Interface()
    err := decode(data, decoded)
    ...

Related links:

Golang interface{} type misunderstanding

How to copy an interface value in Go?

Use the following code to create a copy of the draft struct and unmarshal to it:

t := reflect.TypeOf(methodsMap[Method(base.Method)])
pv := reflect.New(t)
err := json.Unmarshal(p, pv.Interface())
return pv.Elem().Interface(), err  // pv.Elem() dereferences ptr 

playground example