2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CSVファイルを型安全に取り扱う

Posted at

csv ファイルを型付きのオブジェクトとして読み込みたい。

例えば、以下のような csv ファイルであれば {name: string, age: string, gender: string}[] 型として読み込みたい。

name,age,gender
aaa,18,M
bbb,23,F
ccc,30,M

csv の読み込みは papaparse を利用しています。

import papa from 'papaparse'

const readCSV = <T extends {}>(file: File, config: papa.ParseConfig) =>
    new Promise<papa.ParseResult<T>>(((resolve, reject) => {
        config.complete = ((results: papa.ParseResult<T>, _) => resolve(results))
        config.error = ((error, _) => reject(error))
        papa.parse(file, config)
    }))

// readonly ["name, "age"]
const required = ["name", "age"] as const

// Row<readonly ["name", "age"]> は {name: string, age: string}
type Row<T extends readonly string[]> = {[K in T[number]]: string}

// If header is true, the first row of parsed data will be interpreted as field names.
// An array of field names will be returned in meta, and each row of data will be an object of values keyed by field name instead of a simple array.
readCSV<Row<typeof required>>(file, {header: true})
    .then((results) =>
        required.every(e => results.meta.fields && results.meta.fields.includes(e))
            ? results.data  // {name: string, age: string}
            : undefined
    )

パースされたオブジェクトが期待される型であることはランタイム時にはじめて分かります。(ランタイム時に型はないので、「分かる」という表現は不適かもしれません。)
各行の値がいずれも string 型であることは自明ですが、オブジェクトのキーが期待される名前であることはコンパイル時には分かりません。

そこで、required.every(e => results.meta.fields && results.meta.fields.includes(e)) という処理によって、オブジェクトに期待される名前のキーが存在するかを検証しています。papaparse はオブジェクトのキーを results.meta.fields に格納するため、required 配列のすべての文字列が result.meta.fields に含まれることを確認できます。

results.datarequired 配列で指定したキーをもつオブジェクトとして扱うことができます。つまり、そのオブジェクトの型は required配列の型 ( readonly ["name, "age"] ) を Tとすると {[K in T[number]]: string} になります。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?