Interfaces
Targo interfaces follow Go-style contracts. When the interface is intended to model a real Go interface, the GoInterface marker is part of the contract.
Core Rules
- Use interfaces for behavioral boundaries and substitutability.
- Interfaces with Go-style methods should extend
GoInterface. - Prefer Go-shaped method signatures, including tuple returns such as
[T, error | null], over JavaScript-flavored callback contracts. - Do not assume TypeScript
implementshabits are the source of truth. Validate against current Targo checker behavior and declarations.
Defining a Go Interface
typescript
interface Reader extends GoInterface {
Read(p: slice<byte>): [int, error | null];
}Use GoInterface when the type is supposed to behave like a Go interface boundary, especially for imported Go APIs or Targo declarations that should compile to interface contracts.
Class and Interface Compatibility
Classes can participate in interface-oriented design, but the method shape must still match what Targo and Go expect.
typescript
interface Runner extends GoInterface {
Run(name: string): error | null;
}
class TaskRunner {
Run(name: string): error | null {
if (name == "") {
return new Error("name is required");
}
return null;
}
}Keep the method declarations explicit and Go-shaped. Avoid property-method patterns when the goal is to satisfy a Go interface contract.
When To Prefer Other Tools
- Use
Embedding<{ ... }>()for Go-style struct embedding. - Use
DefinedType<...>()when you need a Go defined type, not just an interface boundary. - Use a plain class without
GoInterfacewhen you are modeling local object behavior rather than a Go interface contract.
Common Mistakes
- Forgetting
GoInterfaceon interfaces that are meant to model Go interfaces. - Assuming ordinary TypeScript interface patterns automatically compile to the same Go contract.
- Treating method-bearing properties as interchangeable with Go methods.
- Reaching for inheritance instead of interfaces plus composition.