A discriminated union is how you type a response

An interface with every field optional describes what a response might contain and lets the compiler agree that a success field exists on an error.

// what it usually looks like: everything optional, nothing checked
interface Result { ok?: boolean; data?: Order; error?: string; }

// a discriminated union: the compiler narrows on the tag
type Result =
  | { status: 'ok'; data: Order }
  | { status: 'error'; code: string; message: string };

if (res.status === 'ok') {
  res.data.total;        // known to exist
} else {
  res.code;              // and data is not accessible here
}

The narrowing is what makes this worth the extra syntax: after the check, the compiler knows which branch it is in and refuses the fields that do not belong. It also makes an exhaustive switch checkable — assigning the value to never in the default case is a compile error when a new variant is added and unhandled. This is the single highest-value TypeScript pattern for anything consuming an API.