```ts
/**
 * Codes a sheet of written-in answers against its ordered steps.
 */
export function recodeAnswerSheet(sheet: Record<string, unknown>): Record<string, unknown> {
  if (typeof sheet !== 'object' || sheet === null) {
    throw new Error('Invalid sheet structure');
  }

  const steps = sheet.steps as any[];
  const entries = sheet.entries as any[];

  if (!Array.isArray(steps) || steps.length === 0) {
    throw new Error('Steps must be a non-empty list');
  }

  if (!Array.isArray(entries)) {
    throw new Error('Entries must be a list');
  }

  const coded: any[] = [];
  const loose: string[] = [];
  const used = new Set<string>();

  for (const entry of entries) {
    if (typeof entry !== 'object' || entry === null) {
      throw new Error('Entry must be an object');
    }

    const text = (entry.text as string).toLowerCase().replace(/\s+/g, ' ').trim();
    let label = "";

    for (const step of steps) {
      if (typeof step !== 'object' || step === null) {
        throw new Error('Step must be an object');
      }

      const { label: stepLabel, wanted, barred, least } = step;

      if (typeof stepLabel !== 'string' || stepLabel.trim() === '' || used.has(stepLabel)) {
        throw new Error('Invalid step label');
      }

      if (!Array.isArray(wanted) || wanted.length === 0) {
        throw new Error('Wanted list must be a non-empty list of strings');
      }

      if (barred && !Array.isArray(barred)) {
        throw new Error('Barred must be a list or undefined');
      }

      const hits = wanted.filter((frag: string) => text.includes(frag));
      const bars = barred ? barred.filter((frag: string) => text.includes(frag)) : [];

      if (hits.length >= least && bars.length === 0) {
        label = stepLabel;
        break;
      }
    }

    if (label === "") {
      loose.push(entry.id);
    } else {
      coded.push({ id: entry.id, label });
      used.add(label);
    }
  }

  const unused = steps
    .map((step: any) => step.label)
    .filter((label: string) => !used.has(label));

  return { coded, loose, unused };
}
```