unrust

TypeScript skill practice

How do you approach this?Writing Idiomatic TypeScript with Clear Types

Published

Quick answer

Idiomatic TypeScript makes both intent and uncertainty visible: use named domain types, narrow values with evidence, model meaningful alternatives explicitly, and keep runtime validation near external boundaries. The shortest generic or assertion-heavy version is not automatically the most idiomatic. Prefer a form that lets a teammate see what inputs are trusted, what failures are possible, and how the surrounding code handles them.

Model meaningful alternatives deliberately

Discriminated unions, optional fields, and narrow return types can make a domain rule easier to inspect when they represent real alternatives. Avoid inventing elaborate type machinery for a simple local value, but do not collapse success, absence, and failure into a vague shape that forces callers to guess.

Use assertions sparingly and explain their evidence

An assertion can document a trusted invariant after a parser or guard, but it should not become the default response to a compiler complaint. If a teammate cannot find the evidence behind a cast, the code is carrying an invisible runtime assumption that deserves validation or a clearer interface.

Original example

Keep an API result's alternatives visible

type LoadResult =
  | { ok: true; user: { id: string } }
  | { ok: false; reason: "not-found" | "forbidden" };

function message(result: LoadResult) {
  return result.ok ? result.user.id : result.reason;
}

This original TypeScript example uses a discriminated union because success and failure lead to different caller decisions. It would be less helpful if the application needed a generic error framework or more metadata, so idiomatic code still depends on the local contract. The key review question is whether the type makes the actual alternatives easier to test and handle.

Checklist

  • Does this TypeScript type represent a real domain alternative or only silence uncertainty?
  • Can a caller see the success and failure paths without a cast?
  • Where is external data validated before entering this typed boundary?

Practice loop

  1. 01Replace one broad TypeScript object type with the smallest named shape that communicates the actual contract.
  2. 02Review a cast and locate the validation or invariant that makes it safe to use.
  3. 03Compare a generic abstraction with a direct branch for clarity at the calling boundary.

Limits of this page

TypeScript idioms vary with compiler settings, framework conventions, generated clients, and team preferences. A short style exercise can focus a review conversation, but it cannot rank developers or determine why a local pattern did not immediately feel familiar.

Source context

Editorially reviewed for Unrust using public language documentation, common code-review practice, and small original examples written for this resource system.

Check your own starting point

One diagnostic session is a snapshot, not causal proof of why a result occurred. It can help you choose a focused next practice step without making a broader claim about your ability.

Take the free diagnostic