JS
GO

JavaScript to Go

10 lessons

Progress0%
1Variables & Types2Functions3Objects → Structs4Async → Goroutines5Errors & Panic6Interfaces7Slices and Maps8Packages and Modules9Testing10Standard Library
All Mirror Courses
JS
GO
Interfaces
MirrorLesson 6 of 10
Lesson 6

Interfaces

Structural typing and Go's implicit interface satisfaction

Introduction

In this lesson, you'll learn about interfaces in Go. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.

Mirror Card
JS
From JavaScript:

In JavaScript, you're familiar with structural typing and go's implicit interface satisfaction.

GO
In Go:

Go has its own approach to structural typing and go's implicit interface satisfaction, which we'll explore step by step.

The Go Way

Let's see how Go handles this concept. Here's a typical example:

GO
Go Example
package main

import "fmt"

// Interface declaration
type Speaker interface {
    Speak() string
}

type Mover interface {
    Move() string
}

// Compose interfaces
type Animal interface {
    Speaker
    Mover
}

// Types implicitly satisfy interfaces — no "implements" keyword
type Dog struct{ Name string }
func (d Dog) Speak() string { return "Woof" }
func (d Dog) Move()  string { return "runs" }

type Robot struct{}
func (r Robot) Speak() string { return "Beep" }
func (r Robot) Move()  string { return "rolls" }

func makeNoise(s Speaker) {
    fmt.Println(s.Speak())
}

// Empty interface — accepts any type
func printAny(v any) { fmt.Println(v) }

func main() {
    makeNoise(Dog{"Rex"})  // Woof
    makeNoise(Robot{})     // Beep
    var a Animal = Dog{"Rex"} // Dog satisfies Animal
    fmt.Println(a.Move())
}

Comparing to JavaScript

Here's how you might have written similar code in JavaScript:

JS
JavaScript (What you know)
// JS uses duck typing — no explicit interface declaration
class Dog {
  speak() { return "Woof"; }
  move()  { return "runs"; }
}

class Robot {
  speak() { return "Beep"; }
  move()  { return "rolls"; }
}

// Any object with speak() works
function makeNoise(animal) {
  console.log(animal.speak());
}

makeNoise(new Dog());   // "Woof"
makeNoise(new Robot()); // "Beep"
Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Go interfaces are satisfied implicitly — no 'implements' declaration needed

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Interface is satisfied if the type has all the required methods

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Interfaces can be composed by embedding other interfaces

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

'any' (alias for interface{}) accepts any type — like JS's any

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Interface values hold (type, value) pairs; nil interface != nil pointer

Step-by-Step Breakdown

1. Implicit Satisfaction

A type satisfies an interface automatically when it has all required methods. No 'implements' keyword needed.

JS
JavaScript
// JS duck typing — just use the object
GO
Go
type Writer interface { Write([]byte) (int, error) }
type File struct{}
func (f File) Write(b []byte) (int,error) { ... }
// File now implicitly implements Writer

2. Interface Composition

Embed interfaces inside other interfaces to compose behaviors. io.ReadWriter = io.Reader + io.Writer.

JS
JavaScript
// Mixins via Object.assign or class extends multiple
GO
Go
type ReadWriter interface {
    Reader  // embeds Reader interface
    Writer  // embeds Writer interface
}

3. Empty Interface (any)

interface{} (or 'any' in Go 1.18+) accepts any type. Use type assertions to recover the concrete type.

JS
JavaScript
function printAny(v) { console.log(v); }
GO
Go
func printAny(v any) { fmt.Println(v) }

// Type assertion
if s, ok := v.(string); ok {
    fmt.Println("string:", s)
}

4. Interface for Testing

Define interfaces for dependencies so you can swap them with mock implementations in tests.

JS
JavaScript
// Jest: jest.fn() replaces the function
GO
Go
type DB interface { Query(sql string) ([]Row, error) }
// Real: SqlDB{}
// Test: MockDB{} with fake Query()
Rule of Thumb
Accept interfaces, return structs — code to interface types in function parameters.

Common Mistakes

When coming from JavaScript, developers often make these mistakes:

  • Go interfaces are satisfied implicitly — no 'implements' declaration needed
  • Interface is satisfied if the type has all the required methods
  • Interfaces can be composed by embedding other interfaces
Common Pitfall
Don't assume Go works exactly like JavaScript. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • Interfaces are satisfied implicitly — any type with the right methods qualifies
  • Compose interfaces by embedding: type RW interface { Reader; Writer }
  • 'any' is the empty interface — use type assertions to recover concrete type
  • Design: accept interfaces in parameters, return concrete types
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your JavaScript code in Go to practice these concepts.
PreviousNext