Skip to content

Project · JavaScript Programming (language in depth)

Project: a typed inventory module

Projectexpert· about 7 hours· 6 steps

The brief

Write the inventory module of DukaanOS, a point-of-sale app for small shops, in TypeScript: validate outside data into a Result type, write generic helpers, update products safely with utility types, speed up lookups with memoize, calm a search box with debounce, and test a notifier with hand-made test doubles.

Why it matters

Product companies ask senior JavaScript developers to write exactly this kind of code: typed, pure where possible, easy to test, and careful at the edges where untrusted data comes in. memoize, debounce and test doubles are also classic interview questions you will now have built yourself.

Skills you practise

  • unknown and type narrowing
  • a Result union type
  • generics with keyof
  • Partial, Omit and Pick
  • memoization
  • debounce with injected timers
  • spies and stubs

What you will have at the end

inventory.ts: a typed, tested inventory module (validation, generic helpers, safe updates, memoize, debounce and a notifier with test doubles).

How it is marked (rubric, 100 points)
Correct behaviourEvery check passes.40
Strong, honest typesunknown at the edges, a Result union, generics with keyof, utility types; no any; tsc --strict passes.25
Testable designTimers and senders injected; pure functions; no hidden global state.20
Can explainYou can explain memoize, debounce and spies, and when each one is the right tool.15

0/6 steps done

Step 1 of 6

Parse outside data into a Result

parseProduct(raw: unknown) returns { ok: true, value } with a clean Product (name trimmed), or { ok: false, error } naming the first bad field: sku like DAL-0001, a non-empty name, a known category, pricePaise a whole number above 0, stock a whole number 0 or more.

Data from a form, a CSV file or another API is unknown until checked. TypeScript's unknown type forces you to check before use: typeof checks narrow it step by step. Returning a Result (a union of a success and a failure shape) instead of throwing makes the failure part of the type, so callers cannot forget to handle it: they must look at result.ok first.

The checks run your code; the types are checked by your editor or tsc, so keep them honest.

Run shows what your code prints. Check runs the step's tests. Ctrl+Enter checks too.