This workspace edits text only. Save your answer as lesson.ts in a project with TypeScript installed, then run the following command. No browser test result or completion is awarded here.
Handle all four states, validate unknown API input, and include an invalid success state marked with @ts-expect-error. Remove that directive once to confirm the compiler rejects the invalid state; restore it for a passing check.
Reference solution and walkthrough
type RequestState<T> = { status: 'idle' } | { status: 'loading' } | { status: 'success'; data: T } | { status: 'error'; error: Error };
const unreachable = (value: never): never => { throw new Error(`Unexpected state: ${String(value)}`); };
export function render(state: RequestState<string>) { switch (state.status) { case 'idle': return 'Start a request'; case 'loading': return 'Loading'; case 'success': return state.data; case 'error': return state.error.message; default: return unreachable(state); } }
export function parseName(input: unknown): RequestState<{ name: string }> { if (typeof input === 'object' && input !== null && 'name' in input && typeof input.name === 'string') return { status: 'success', data: { name: input.name } }; return { status: 'error', error: new Error('Invalid API payload') }; }
// @ts-expect-error success requires data
const invalid: RequestState<string> = { status: 'success' };
Walkthrough
This is a guided compiler exercise, not a browser JavaScript test. Save your implementation as lesson.ts in a project with TypeScript installed.
Use a union discriminated by status. Success requires data and error requires Error; idle and loading require neither. Switch on status to narrow the available fields.
Handle every branch and pass the default value to a never function. Adding a new status then produces a compile error until the renderer handles it.
Validate unknown JSON before building a success state. Type annotations disappear at runtime; the parseName guard checks the object and name property.
Run npx tsc --strict --noEmit --target ES2022 --skipLibCheck lesson.ts. The reference solution must pass with @ts-expect-error present and fail when that directive is removed.
Acceptance checklist
The solution compiles with the supplied strict command.
Remove @ts-expect-error: success without data must fail compilation.
Add a cancelled branch without updating render: exhaustiveness must fail.
parseName({name: "Ada"}) succeeds; null and {name: 3} return error.