A small union type can model the allowed states in a workflow.

state transition Returning a new state from a function keeps workflow changes explicit and typed.

State Transition Case

current
state.ts
Replay: real traced execution (multi-file project)
type Status = "draft" | "review" | "published";

function advance(status: Status): Status {
    if (status === "draft") {
        return "review";
    }

    if (status === "review") {
        return "published";
    }

    return "published";
}

const current: Status = "draft";
const next: Status = advance(current);

console.log(`next=${next}`);
type Status = "draft" | "review" | "published";

function advance(status: Status): Status {
    if (status === "draft") {
        return "review";
    }

    if (status === "review") {
        return "published";
    }

    return "published";
}

const current: Status = "review";
const next: Status = advance(current);

console.log(`next=${next}`);
  1. current ← draft

    12    return "published";13}1415const current→ draft: Status = "draft";  //@current="review"16const next: Status = advance(currentdraft);
  2. function advance(status: Status): Status

    1type Status = "draft" | "review" | "published";23function advance(statusdraft: Status): Status {4    if (status === "draft") {
  3. if (status === "draft")

    3function advance(status: Status): Status {4    if (statusdraft === "draft") {5        return "review";6    }
  4. next ← review

    15const current: Status = "draft";  //@current="review"16const next→ review: Status = advance(currentdraft);1718console.log(`next=${nextreview}`);
    outputnext=review
  1. current ← review

    12    return "published";13}1415const current→ review: Status = "review";16const next: Status = advance(currentreview);
  2. function advance(status: Status): Status

    1type Status = "draft" | "review" | "published";23function advance(statusreview: Status): Status {4    if (status === "draft") {
  3. if (status === "review")

    5    return "review";6}78if (statusreview === "review") {9    return "published";10}
  4. next ← published

    15const current: Status = "review";16const next→ published: Status = advance(currentreview);1718console.log(`next=${nextpublished}`);
    outputnext=published