Skip to content

Instantly share code, notes, and snippets.

@jspears
Last active February 9, 2022 19:01
Show Gist options
  • Save jspears/50339ed7a344302908e9e2f2be6061e4 to your computer and use it in GitHub Desktop.
Save jspears/50339ed7a344302908e9e2f2be6061e4 to your computer and use it in GitHub Desktop.
Parsing CSV with TypeScript Types

Ever need to parse CSV with TypeScript, no? Me niether but here goes.

I redid this one so that can handle quotes more correctly. No that CSV actually parsable, but at least it may almost might be right. I'd like to add csv to objects instead of array of arrays... but I gotta think on that.

type Line<T, D extends string = ',', R extends string[] = []> = 
    T extends '' ? R :
    T extends ` ${infer Rest}` ? Line<Rest, D, R> :
    T extends `${infer Rest} ` ? Line<Rest, D, R> : 
    T extends `"${infer Field}"${D}${infer Rest}` ? Line<Rest, D, [...R, Field]> :
    T extends `'${infer Field}'${D}${infer Rest}` ? Line<Rest, D, [...R, Field]> :
    T extends `${infer Field}${D}${infer Rest}` ? Line<Rest, D, [...R, Field]> :
    [...R, T];


type Lines<T, D extends string = ',', R extends string[][] = []> = 
T extends '' ? R :
T extends `${infer L}\n${infer N}` ? [ ...R, Line<L, D>, ...Lines<N, D>] :
[...R, Line<T,D>];


type CSV<T, D extends string = ',', R extends string[][] = []> = 
    T extends '' ? R : 
    T extends `#${infer Header}\n${infer Rest}` ? [Line<Header, D>, ...Lines<Rest, D>] :
    [...R, ...Lines<T, D>];


type L1 = Line<'all,good,dogs'>;
type L2 = Line<'"all, good " , dogs'>;
type L3 = Line<'all, "good dogs"'>;

type H1 = CSV<`#id,name,age\n1, "alice jo", 22\n2, 'bob ann', 33\n '3 3', super, do`>
type S1 = CSV<`id,name,age\n1, "alice jo", 22\n2, 'bob ann', 33\n '3 3', super, do`>
type D1 = CSV<`id|name|age\n1| "alice jo"| 22\n2| 'bob ann'| 33\n '3 3'| super| do`, "|">

playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment