diff --git a/compiler/statements.go b/compiler/statements.go index 529f40a39..43a526d5d 100644 --- a/compiler/statements.go +++ b/compiler/statements.go @@ -123,7 +123,9 @@ func (c *funcContext) translateStmt(stmt ast.Stmt, label *types.Label) { var bodyPrefix []ast.Stmt if implicit := c.p.Implicits[clause]; implicit != nil { value := refVar - if _, isInterface := implicit.Type().Underlying().(*types.Interface); !isInterface { + if typesutil.IsJsObject(implicit.Type().Underlying()) { + value += ".$val.object" + } else if _, ok := implicit.Type().Underlying().(*types.Interface); !ok { value += ".$val" } bodyPrefix = []ast.Stmt{&ast.AssignStmt{ diff --git a/js/js_test.go b/js/js_test.go index f96cac143..cbac7c7db 100644 --- a/js/js_test.go +++ b/js/js_test.go @@ -571,3 +571,29 @@ func TestUint8Array(t *testing.T) { t.Errorf("Non-empty byte array is not externalized as a Uint8Array") } } + +func TestTypeSwitchJSObject(t *testing.T) { + obj := js.Global.Get("Object").New() + obj.Set("foo", "bar") + + want := "bar" + + if got := obj.Get("foo").String(); got != want { + t.Errorf("Direct access to *js.Object field gave %q, want %q", got, want) + } + + var x interface{} = obj + + switch x := x.(type) { + case *js.Object: + if got := x.Get("foo").String(); got != want { + t.Errorf("Value passed through interface and type switch gave %q, want %q", got, want) + } + } + + if y, ok := x.(*js.Object); ok { + if got := y.Get("foo").String(); got != want { + t.Errorf("Value passed through interface and type assert gave %q, want %q", got, want) + } + } +}