export type TodoStatus = 'pending' | 'in_progress' | 'completed' | 'cancelled' export interface TodoItem { content: string id: string status: TodoStatus } const STATUSES: readonly TodoStatus[] = ['pending', 'in_progress', 'completed', 'cancelled'] const isRecord = (v: unknown): v is Record => Boolean(v && typeof v === 'object' && !Array.isArray(v)) const isStatus = (v: unknown): v is TodoStatus => (STATUSES as readonly string[]).includes(v as string) function parseArray(value: unknown[]): TodoItem[] { return value.flatMap(item => { if (!isRecord(item) || !isStatus(item.status)) { return [] } const id = String(item.id ?? '').trim() const content = String(item.content ?? '').trim() return id && content ? [{ content, id, status: item.status }] : [] }) } function parse(value: unknown, depth: number): null | TodoItem[] { if (depth > 2) { return null } if (Array.isArray(value)) { return parseArray(value) } if (typeof value === 'string' && value.trim()) { try { return parse(JSON.parse(value), depth + 1) } catch { return null } } if (isRecord(value) && Object.hasOwn(value, 'todos')) { return parse(value.todos, depth + 1) } return null } export const parseTodos = (value: unknown): null | TodoItem[] => parse(value, 0)