In this case, MyString is a string as far as reflect.ValueOf.Kind is concerned:
fmt.Println(v.Kind()) // string// Even though MyString implements a custom TextUnmarshaler, the ValueOf.Kind check is used first.vartextUnmarshalerType=reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
fmt.Println(reflect.PtrTo(v2.Type().Key()).Implements(textUnmarshalerType)) // true
Because the string key case is checked first, your custom UnmarshalText or UnmarshalJSON on your map key type will not be used.
As a workaround, you can define a custom map type that defines UnmarshalJSON and does the work you want, but it will not be as clean as you expect in your example. I'll let the domain experts take over from here.
To unmarshal a JSON object into a map, Unmarshal first establishes a map to use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal reuses the existing map, keeping existing entries. Unmarshal then stores key-value pairs from the JSON object into the map. The map's key type must either be a string, an integer, or implement encoding.TextUnmarshaler.
Note that it mentions encoding.TextUnmarshaler for map keys, but not json.Unmarshaler. Why do you think your code should be doing something different?
The path to resolution is known, but the work has not been done.
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Issue is not actionable because of missing required information, which needs to be provided.
May 6, 2020