```ts
/**
 * Split a CSV line into its fields on commas.
 * A field wrapped in double quotes may contain commas,
 * and a doubled quote inside such a field means one literal quote character;
 * the surrounding quotes are not part of the value. Fields that are not quoted are taken literally,
 * including any surrounding spaces. An empty line is one empty field.
 * Throw an Error for a quoted field that is never closed.
 * @param line - The CSV line to parse.
 * @returns An array of fields.
 */
export function parseCsvLine(line: string): string[] {
  const result: string[] = [];
  let currentField = '';
  let inQuotes = false;
  let quotesCount = 0;

  for (let i = 0; i < line.length; i++) {
    const char = line[i];
    if (!inQuotes && char === ',') {
      // End of field
      result.push(currentField.trim());
      currentField = '';
    } else if (char === '"') {
      inQuotes = !inQuotes;
      quotesCount++;
    } else if (inQuotes) {
      currentField += char;
    } else {
      currentField += char;
    }
  }

  // Handle the last field
  result.push(currentField.trim());

  // Check for unclosed quoted fields
  if (quotesCount % 2 !== 0 && quotesCount > 0) {
    throw new Error('Unquoted field not closed');
  }

  return result;
}
```