Home CSV to TypeScript
CSV to TypeScript interface generator
Paste a CSV file and get the interface describing one parsed row. Column types come from the values, not from the header.
The type depends on how you parse, not on the file
A CSV file has no types. Every cell is text, so the interface that describes a parsed row depends entirely on what your parser did — and this is the mismatch that produces a type which is correct on this page and wrong in your code.
With type detection on, the interface describes rows from a parser that
converts values: signups: number, active: boolean. That matches
csv-parse with cast: true, Papa Parse with
dynamicTyping: true, or pandas.
With detection off, every field is string — which is what a
plain split(','), a default Papa Parse, or csv-parse without
casting actually gives you. If your runtime types disagree with your compile-time types,
this switch is usually the reason.
The leading-zero rule applies here too
Even with detection on, 01234 stays a string, because a value is converted
only when writing the number back out reproduces the original text exactly. So a zip code
column is typed string while a quantity column is typed number —
which is right, and is what a naive cast gets wrong in both directions.
One interface, not a nested tree
A CSV row is flat, so the output is a single interface with one property per column. A
column named user.name becomes a quoted key 'user.name' rather
than a nested object: dots in a CSV header are part of the name, and reading them as
structure would reshape any file whose columns happen to contain a full stop.
If you want the nested version, convert to JSON first with the CSV to JSON converter and paste that into the JSON generator.
Empty cells
With detection on an empty cell is null, so a column that is empty anywhere
is typed string | null. That is usually what you want and occasionally not —
if your parser produces '' for an empty cell rather than null, turn detection
off and the whole row is strings.
Paste enough rows
Types come from the values present, so a five-row paste describes those five rows. The column that is empty only on row 900, or numeric until someone typed "N/A", will not show up. Paste the header plus a genuinely representative sample — including the rows you know are awkward.
Common questions
Why is my number column typed as string?
Either type detection is off, or the values are not plain numbers — a leading zero, a trailing zero after a decimal point, thousands separators or a currency symbol all keep a column as text, deliberately.
Which parser does the output match?
With type detection on it matches a parser that casts values: csv-parse with cast: true, Papa Parse with dynamicTyping: true, or pandas. With detection off it matches a plain split or a default Papa Parse, where every field is a string.
How do I get nested interfaces from a CSV?
You cannot directly, because a CSV row is flat. Convert to JSON first, then paste that into the JSON to TypeScript generator.
What happens to a column with empty cells?
With type detection on an empty cell becomes null, so the column is typed as a union with null. With detection off it stays an empty string and the column is just string.
How many rows should I paste?
Enough to be representative. Types are inferred from the values present, so a column that is only awkward on row 900 will not be reflected in a five-row sample.
Related
- /csv-to-json-converter — converting the file itself rather than describing it.
- /json-to-typescript — nested interfaces, from JSON.
- /csv-to-sql-converter — a table definition instead of an interface.
- /sample-csv-files — sample CSV files to try it on.
Last updated