Advanced TypeScript for Harness Builders

0b. Interfaces & Type Aliases

Two ways to name an object shape — and when to reach for which.

These are the two ways to name an object shape. JavaScript has neither.

Interface — defines an object shape:

File: packages/mom/src/sandbox.ts L79-101

export interface Executor {
  exec(command: string, options?: ExecOptions): Promise<ExecResult>;
  getWorkspacePath(hostPath: string): string;
}

export interface ExecOptions {
  timeout?: number;
  signal?: AbortSignal;
}

export interface ExecResult {
  stdout: string;
  stderr: string;
  code: number;
}

An interface describes what an object must look like. Any object that has these fields with these types is compatible — no implements keyword needed for plain objects.

Type alias — names any type:

File: packages/mom/src/sandbox.ts L3

export type SandboxConfig = { type: "host" } | { type: "docker"; container: string };

When to use which:

  • interface for object shapes that might be extended or implemented by classes
  • type for unions, intersections, mapped types, or anything that isn’t just an object shape
  • This project uses interface for data contracts and type for unions consistently

Class implementing an interface:

File: packages/mom/src/sandbox.ts L104-106

class HostExecutor implements Executor {
  async exec(command: string, options?: ExecOptions): Promise<ExecResult> { ... }
  getWorkspacePath(hostPath: string): string { return hostPath; }
}

Open this chapter inside the full course