An interface type-assertion asserts that the dynamic value in the interface (in this case it's `string`) implements the interface you are asserting (in this case `myinterface`). As `myinterface` has no methods, every value implements that interface.
In general, a type-assertion will assert things about the dynamic value stored in an interface. In that code, the dynamic value is `string` *either way*. In one case, you assign a `string` to `interface{}`, in the other you assign a `string` to `myinterface`. But both will ultimately store a `string`. That's also why your first case, using `mystring` works as expected - in that case, the dynamic type is `string` in one case and `mystring` in the other (note that the dynamic type is *always* a "concrete type", not an interface).
In general, ways to get around this is to either a) not use an interface, or b) give that interface a method only specific types implement, or c) store a `*myinterface` - it's a pointer, not an interface, thus a concrete type, which can be distinguished. However, in your case, neither of these strategies would likely be fruitful. The `json` package needs to know how to store the values it decodes and it won't be able to, if it doesn't have a concrete type or a `json.Unmarshaler`.
So in your specific case, you might want to consider using something like
type struct {
s string
n int64
isString bool
}
and have that implement `json.Marshaler` and `json.Unmarshaler`.