⚒️

CSVの列群をプロパティとして持つ行クラスを定義する

2022/08/03に公開

test.csv

name,address,age
Taro,Tokyo,14
Keiko,Osaka,32
Risa,Kanagawa,17

TypeScript で CSV を読み込む処理を普通に自作するとたぶんこんな感じになると思う。

const rows: new Map<string, string>[] = loadCsv();

for (const row of rows) {
  const name = row['name'];
  const address = row['address'];
  const age = row['age'];
  console.log(`name/address/age`, name, address, age);
}

読み込んだあと、できるだけタイプセーフに扱いたい(row['address'] じゃなくて row.address と使いたい)。

こんな感じになった。

class CsvRow<T extends string> {
  constructor(public columns: { [K in T]: string }) {}
}

const AddressColumns = [
  'name', 
  'address', 
  'age'
] as const;
type Address = typeof AddressColumns[number];

const rows: CsvRow<Address>[] = loadCsv<<Address>>();

for (const row of rows) {
  const name = row.columns.name;
  const address = row.columns.address;
  const age = row.columns.age;
  const zip = row.columns.zip;  // これはコンパイルエラー
  console.log(`name/address/age`, name, address, age);
}

console.log(new CsvRow<Address>({
  address: 'tokyo',
  age: '12',
  name: 'taro',
  zip: 'aaa',  // これはコンパイルエラー
}).columns);

AddressColumnsAddress のいい感じの命名がわからん。

実際に CSV をパースするなら、 papaparse - npm など、既存のライブラリを使います。

参考

Discussion