Problem Statement
Implement fetchJson<T> that validates/narrows unknown data safely.
Explanation
Step 1: fetch and parse as unknown. Step 2: validate with a type guard or schema. Step 3: return `T` only if validation passes. This avoids `any` leaks and catches bad API responses early.
Code Solution
SolutionRead Only
type Guard<T> = (x: unknown) => x is T;
export async function fetchJson<T>(url: string, isT: Guard<T>, init?: RequestInit): Promise<T> {
const res = await fetch(url, init);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data: unknown = await res.json();
if (!isT(data)) throw new Error('Invalid shape');
return data; // safely T
}
// Example guard
interface User { id: number; name: string }
const isUser: Guard<User> = (x: unknown): x is User =>
typeof x === 'object' && x !== null &&
typeof (x as any).id === 'number' && typeof (x as any).name === 'string';
// Usage: const user = await fetchJson<User>('/api/user/1', isUser);