The $assertType helper only considers the method set when asserting if a type implement an interface. But with struct embedding, it is possible for a struct field to shadow a method.
This fails gopherjs run:
package main
type Doer interface {
Do()
}
type Embedded struct{}
func (e *Embedded) Do() {}
type A struct {
Embedded
Do string
}
func main() {
var a interface{}
a = &A{}
if aa, ok := a.(Doer); ok {
aa.Do()
}
}
It incorrectly considers a a Doer and ends up failing with:
TypeError: aa.Do is not a function
If anyone else was confused (as I was :), the point is not that aa.Do() should call A.Embedded.Do(), the point is that the type assertion should've failed: a is not actually a Doer:
// In the regular Go playground
if aa, ok := a.(Doer); ok {
aa.Do()
} else {
println("not a doer")
}
// => not a doer
@theclapp That's correct, I updated to the description in an effort to make that clearer.
So, is $assertType wrong, and needs to look into properties of the type too, or should this method not be in the methodset of the type to begin with?
Most helpful comment
If anyone else was confused (as I was :), the point is not that aa.Do() should call A.Embedded.Do(), the point is that the type assertion should've failed:
ais not actually a Doer: