Good Code
The good version ties each shape to a clear status, so TypeScript can narrow the available fields in each branch.
Lesson 04
Model related states with a discriminant so callers can narrow safely.
type SaveResult =
| { status: "saved"; id: string }
| { status: "failed"; message: string };
function renderSaveResult(result: SaveResult) {
// The status field selects the only valid shape for each branch.
if (result.status === "saved") {
return "Saved draft " + result.id;
}
return "Could not save: " + result.message;
}type SaveResult = {
saved?: boolean;
id?: string;
message?: string;
};
function renderSaveResult(result: SaveResult) {
// Optional fields allow impossible combinations to compile.
if (result.saved) {
return "Saved draft " + result.id;
}
return "Could not save: " + result.message;
}The good version ties each shape to a clear status, so TypeScript can narrow the available fields in each branch.
The bad version leaves optional fields to be guessed together, allowing states like saved: true without an id or a failure without a message.