TS
GO

TypeScript to Go

10 lessons

Progress0%
1Introduction: Transpiled to Compiled Binary2Type Systems: Structural Interfaces3Functions4Objects to Structs5Generics6Error Handling7Async to Goroutines8Ecosystem9Testing10Go Standard Library
All Mirror Courses
TS
GO
Type Systems: Structural Interfaces
MirrorLesson 2 of 10
Lesson 2

Type Systems: Structural Interfaces

Type Systems

Introduction

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

Mirror Card
TS
From TypeScript:

In TypeScript, you're familiar with type systems.

GO
In Go:

Go has its own approach to type systems, 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
// Go: structural typing via implicit interface satisfaction
type Writer interface {
    Write(data string)
}

// FileWriter implicitly satisfies Writer — no declaration
type FileWriter struct{}

func (f FileWriter) Write(data string) {
    fmt.Printf("Writing: %s\n", data)
}

func output(w Writer) {
    w.Write("hello")
}

// FileWriter satisfies Writer implicitly — like TypeScript!
output(FileWriter{})

Comparing to TypeScript

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

TS
TypeScript (What you know)
// TypeScript: structural typing
interface Writer {
  write(data: string): void;
}

// No explicit declaration needed — shape is enough
const fileWriter = {
  write(data: string) { console.log(`Writing: ${data}`); }
};

function output(w: Writer) {
  w.write("hello");
}

output(fileWriter); // Works — shape matches
Mirror Card
TS
From TypeScript:

You may be used to different syntax or behavior.

GO
In Go:

Go interfaces are satisfied implicitly — like TypeScript structural typing

Mirror Card
TS
From TypeScript:

You may be used to different syntax or behavior.

GO
In Go:

Go has no implements keyword — if a type has the methods, it satisfies the interface

Mirror Card
TS
From TypeScript:

You may be used to different syntax or behavior.

GO
In Go:

Go types are more primitive: no class hierarchy, just structs + methods

Mirror Card
TS
From TypeScript:

You may be used to different syntax or behavior.

GO
In Go:

Go is statically compiled but structurally typed — the best of both worlds

Step-by-Step Breakdown

1. Implicit Interface Satisfaction

Go interfaces work like TypeScript interfaces — if a type has all the required methods, it satisfies the interface automatically without any declaration.

TS
TypeScript
interface Greetable { greet(): string; }
const x = { greet() { return "hi"; } };
const g: Greetable = x; // OK — structural
GO
Go
type Greetable interface {
    Greet() string
}

type Person struct{ Name string }
func (p Person) Greet() string { return "hi " + p.Name }
// Person implicitly satisfies Greetable
Rule of Thumb
Define small interfaces with 1-2 methods. The Go proverb: 'the bigger the interface, the weaker the abstraction.'

2. No Classes — Structs + Methods

Go has no classes. Data lives in structs. Behavior is added via methods with a receiver. This is like TypeScript interfaces plus separate function implementations.

TS
TypeScript
class Rectangle {
  constructor(public width: number, public height: number) {}
  area(): number { return this.width * this.height; }
}
GO
Go
type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

3. No Inheritance

Go has no inheritance. Composition is achieved with struct embedding — a struct can embed another struct and its methods are promoted.

TS
TypeScript
class ColoredRect extends Rectangle {
  constructor(width: number, height: number, public color: string) {
    super(width, height);
  }
}
GO
Go
type ColoredRect struct {
    Rectangle        // embedded — promotes Width, Height, Area()
    Color string
}

cr := ColoredRect{Rectangle{10, 5}, "red"}
fmt.Println(cr.Area()) // promoted method

4. any and interface{}

Go's any (alias for interface{}) is the equivalent of TypeScript's unknown/any — a value that can hold anything. Use type assertions to extract the concrete type.

TS
TypeScript
function process(val: unknown): void {
  if (typeof val === "string") { console.log(val.length); }
}
GO
Go
func process(val any) {
    if s, ok := val.(string); ok {
        fmt.Println(len(s))
    }
}

Common Mistakes

When coming from TypeScript, developers often make these mistakes:

  • Go interfaces are satisfied implicitly — like TypeScript structural typing
  • Go has no implements keyword — if a type has the methods, it satisfies the interface
  • Go types are more primitive: no class hierarchy, just structs + methods
Common Pitfall
Don't assume Go works exactly like TypeScript. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • Go interfaces are satisfied implicitly — same structural philosophy as TypeScript
  • No classes: use structs for data, methods for behavior
  • No inheritance: use struct embedding for composition
  • any (interface{}) is Go's equivalent of TypeScript's unknown
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your TypeScript code in Go to practice these concepts.
PreviousNext