TypeDrop
2026-07-26 Challenge
2026-07-26
Easy
Typed Safe JSON Parser with Result Type
You're building the configuration-loading layer for a CLI tool. Raw JSON strings arrive from config files, environment variables, and remote endpoints — any of which can be malformed or structurally wrong. You need a small, strongly-typed parsing toolkit that turns `unknown` blobs into validated, shaped data without ever reaching for `any` or unsafe type assertions.
Goals
- Define a two-variant discriminated-union Result<T, E> and a three-kind ParseError union.
- Implement safeParseJSON that maps empty input, syntax failures, and valid JSON to the correct Result variants.
- Build validateString, validateNumber, validateBoolean, and a generic validateObject using a mapped-type schema.
- Compose everything in parseTo<T> and implement the generic mapResult helper.
challenge.ts
// Core types you must define and implement:
type Result<T, E> =
| { ok: true; value: T }
| { ok: false; error: E };
type ParseError =
| { kind: "SyntaxError"; message: string }
| { kind: "ValidationError"; message: string }
| { kind: "EmptyInput"; message: string };
type Validator<T> = (value: unknown) => Result<T, ParseError>;
// Compose them all in the top-level entry point:
function parseTo<T>(
raw: string,
validator: Validator<T>
): Result<T, ParseError> { ... }
// Example schema-driven object validator:
const configValidator = validateObject<{ host: string; port: number }>({
host: validateString,
port: validateNumber,
});
Hints (click to reveal)
Hints
- The schema parameter of validateObject should be typed as `{ [K in keyof T]: Validator<T[K]> }` — let the mapped type do the heavy lifting so callers get field-level type checking for free.
- In validateObject, after confirming the input is a non-null, non-array object, iterate over Object.keys(schema) and run each validator — cast the field lookup with a keyof assertion only where the compiler can't narrow automatically.
- mapResult only needs a single if/else on `result.ok` — the discriminated union will narrow both branches for you with no type assertions needed.
Useful resources
Or clone locally
git clone -b challenge/2026-07-26 https://github.com/niltonheck/typedrop.git