Ask ChatGPT for TypeScript that catches a missing union case

When a screen has loading, ready and failed states, ask ChatGPT to model them as separate union members and check every case. An exhaustive switch can turn a newly added state into a compiler error at the renderer that still needs updating. Making every property optional loses that relationship.

For this practice example, a download status has a filename only when it is ready. An error message belongs only to the failed state. The goal is to make those rules visible to TypeScript before anyone connects the renderer to an API.

Encode the states separately

Save this authored example as status.ts:

type DownloadState =
  | { kind: "loading" }
  | { kind: "ready"; filename: string }
  | { kind: "failed"; message: string };

function describeDownload(state: DownloadState): string {
  switch (state.kind) {
    case "loading":
      return "Preparing download";
    case "ready":
      return `Ready: ${state.filename}`;
    case "failed":
      return `Failed: ${state.message}`;
    default: {
      const unhandled: never = state;
      return unhandled;
    }
  }
}

console.log(describeDownload({ kind: "loading" }));
console.log(describeDownload({ kind: "ready", filename: "agenda.pdf" }));
console.log(describeDownload({ kind: "failed", message: "Try again" }));

The literal kind property identifies each member. Inside the ready branch, the compiler knows filename exists. It does not need a non-null assertion to overlook a missing filename.

The TypeScript narrowing handbook, checked October 24, 2026, explains discriminated unions and never exhaustiveness checks. Here, the default branch says that no unhandled member should remain after the three cases.

Make the compiler expose an incomplete change

Use your project's installed TypeScript compiler. For a small standalone exercise, its compile command can be:

tsc --strict --target ES2020 status.ts
node status.js

This assumes tsc and Node are already available in your terminal. In an existing repository, use its established type-check command and configuration instead of creating a second build setup.

The expected messages are:

Preparing download
Ready: agenda.pdf
Failed: Try again

Now add | { kind: "cancelled" } to the type without changing the function. The assignment to never should fail because a cancelled state can reach that branch. Add a cancelled case with the text your interface actually needs, then type-check again.

That exercise distinguishes a renderer whose cases are checked from a renderer that happens to display today's three fixtures. A default return such as “Unknown” would hide the new missing case from this particular exhaustiveness check.

Give ChatGPT the failure you want to prevent

Review this TypeScript state renderer under strict mode.
Actual TypeScript version and project type-check command: [PASTE]
Current code: [PASTE]

Model loading, ready and failed as a discriminated union.
Ready alone has filename:string; failed alone has message:string.
Use an exhaustive switch that fails type-checking when a new union
member is added without its rendering case. Do not use any, casts,
non-null assertions or an unknown-state fallback to silence errors.

Show expected outputs for the three valid states. Then show the
deliberate cancelled-member change and explain the compiler error
it should cause. Preserve the existing message wording. Do not add
network requests, dependencies or claim a compiler run you did not do.

OpenAI's prompting guidance supports supplying the relevant context and required output. In this case, asking for a deliberate failing variation makes the intended protection testable.

Keep runtime input checks at the boundary

A union annotation does not validate arbitrary JSON arriving from a server. This function's input contract assumes a valid DownloadState; an unchecked cast of API data would bypass that contract. Use your application's existing parser or validator before calling it. For conditional JSON input rules, the JSON Schema guide addresses that separate boundary.

Keep both the valid fixtures and the missing-case check with the change. When the product adds a cancelled state, the compiler should lead you to the wording that still needs a decision.

Keep reading