Работа с CSV в TypeScript: библиотеки и примеры кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с CSV в TypeScript: полное руководство

CSV (Comma-Separated Values) — один из самых распространённых форматов для обмена табличными данными. В экосистеме TypeScript доступно несколько мощных библиотек, которые позволяют читать, писать и преобразовывать CSV-файлы с полной поддержкой типов. В этой статье мы разберём основные инструменты, их установку и практические примеры.

Популярные библиотеки для работы с CSV

Наиболее часто используемые библиотеки в TypeScript/Node.js среде:

  • csv-parse — часть набора csv, надёжный парсер с поддержкой потоков
  • papaparse — универсальный парсер для браузера и Node.js
  • csv-stringify — генератор CSV из массивов/объектов
  • csvtojson — конвертер CSV в JSON с типизацией

Установка и настройка

Для проектов на TypeScript установка производится через npm или yarn:

npm install csv-parse csv-stringify papaparse @types/papaparse

Если вы используете csv-parse, дополнительные типы не требуются — библиотека имеет встроенную поддержку TypeScript.

Пример 1: Парсинг CSV с помощью csv-parse

Библиотека csv-parse отлично подходит для работы с большими файлами благодаря stream API. Рассмотрим базовый пример:

import { parse } from 'csv-parse/sync';
import * as fs from 'fs';

interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

const csvData = fs.readFileSync('users.csv', 'utf-8');

const records: User[] = parse(csvData, {
  columns: true,       // первая строка — заголовки
  skip_empty_lines: true,
  delimiter: ',',
  cast: (value, context) => {
    if (context.column === 'id' || context.column === 'age') {
      return Number(value);
    }
    return value;
  }
});

console.log(records);
// [
//   { id: 1, name: 'Иван', email: 'ivan@example.com', age: 30 },
//   { id: 2, name: 'Мария', email: 'maria@example.com', age: 25 }
// ]

Пример 2: Генерация CSV с типизацией

Для создания CSV-файлов используйте csv-stringify. Определим тип данных и сгенерируем строку:

import { stringify } from 'csv-stringify/sync';

interface Product {
  productId: string;
  name: string;
  price: number;
  inStock: boolean;
}

const products: Product[] = [
  { productId: 'P001', name: 'Ноутбук', price: 75000, inStock: true },
  { productId: 'P002', name: 'Мышь', price: 1500, inStock: false },
  { productId: 'P003', name: 'Клавиатура', price: 3500, inStock: true }
];

const csvOutput = stringify(products, {
  header: true,
  columns: ['productId', 'name', 'price', 'inStock']
});

console.log(csvOutput);
// productId,name,price,inStock
// P001,Ноутбук,75000,true
// P002,Мышь,1500,false
// P003,Клавиатура,3500,true

Пример 3: Использование PapaParse в браузере

PapaParse идеален для клиентской обработки CSV. Пример с загрузкой файла через input:

import Papa from 'papaparse';

interface Transaction {
  date: string;
  amount: number;
  category: string;
  description: string;
}

const fileInput = document.getElementById('csvInput') as HTMLInputElement;

fileInput.addEventListener('change', (event) => {
  const file = (event.target as HTMLInputElement).files?.[0];
  if (!file) return;

  Papa.parse<Transaction>(file, {
    header: true,
    dynamicTyping: true,  // автоматическое преобразование типов
    skipEmptyLines: true,
    complete: (result) => {
      console.log('Парсинг завершён:', result.data);
      // result.data — массив объектов Transaction
    },
    error: (error) => {
      console.error('Ошибка парсинга:', error);
    }
  });
});

Пример 4: Обработка больших файлов потоком

Для файлов размером более 100 МБ используйте потоковую обработку с csv-parse:

import { createReadStream } from 'fs';
import { parse } from 'csv-parse';
import { Transform } from 'stream';

interface LogEntry {
  timestamp: string;
  level: string;
  message: string;
}

const parser = parse({
  columns: true,
  delimiter: ',',
  relax_column_count: true
});

const transformer = new Transform({
  objectMode: true,
  transform(record: LogEntry, encoding, callback) {
    // Преобразование данных
    record.level = record.level.to                    

Рекомендаций