interface
interface Name: declares a structural contract. Lowered to class Name(Protocol): from typing.
interface Drawable: def draw(self) -> None def width(self) -> float def height(self) -> floatMembers
An interface may declare:
- Method signatures:
def name(self, ...) -> R(no body —...is implicit). - Field signatures:
name: T.
interface Stored: id: int def serialise(self) -> dict[str, str]Structural conformance
A class satisfies an interface if it provides every required member with compatible signatures. No implements clause:
class Button: label: str
impl Button: def draw(self) -> None: ... def width(self) -> float: return 10.0 def height(self) -> float: return 1.0
def render(d: Drawable) -> None: ...render(Button(label="x")) # ✅ structurally matchesThe checker verifies at the call / assignment site.
isinstance is rejected by default
isinstance(x, Drawable) # ❌ tyc::interface_isinstanceUse static narrowing or refactor to a sealed union. See Interfaces (Protocols) for the full reasoning.
Generic interfaces
interface Container[T]: def add(self, item: T) -> None def items(self) -> list[T]Bound at the use site:
def consume[T](c: Container[T]) -> int: return len(c.items())Bounded type parameters
Interfaces are valid as bounds for generic type parameters:
def smallest[T: Ordered](xs: list[T]) -> T?: ...(Bounded inference is partial in v1; verify with tyc check.)
Emit
interface Drawable: def draw(self) -> Nonefrom typing import Protocol
class Drawable(Protocol): def draw(self) -> None: ...Where next
- Interfaces (Protocols) — the type system reference.
- Sealed Unions — the closed-set alternative.
- Generics — bounded type parameters.