Skip to content

Instantly share code, notes, and snippets.

@jspears
Created February 10, 2022 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jspears/4cb7b649b366a20256d4f589b26af84f to your computer and use it in GitHub Desktop.
Save jspears/4cb7b649b366a20256d4f589b26af84f to your computer and use it in GitHub Desktop.
TypeScript/Types Parsing properties with TypeScript

So properties files are useful sometimes. They can story configurations and stuff. So parsing them is not hard, but multi-line values and other gotchas are well -- a little tricky.

type Join<T, D extends string =' ', Ret extends string = ''> = T extends [infer First, ...infer Rest] ?
     First extends string ? Join<Rest, D, Ret extends '' ? First : `${Ret}${D}${First}`>  : Join<Rest,D,Ret> : Ret ; 

type ParseLine<T, Ret extends [string,string] = ['','']> = 
    T extends '' ? Ret :
    T extends (`${infer Left}\\n${infer Rest}` ) ?
    ParseLine<Rest, [ Join<[Left, Ret[0]]>, Ret[1]]> :
    T extends `${infer Left}#${string}\n${infer Rest}`  ? [ Join<[Left, Ret[0]]>, Rest] :
    T extends (`${infer Left}\n${infer Rest}`) ? [ Join<[Left, Ret[0]]>, Rest]
    : Ret;



type Trim<T> = T extends (` ${infer Value}` | `${infer Value} ` | `${infer Value}\n`) ? Trim<Value> : T;

type ParseProperties<T, Ret extends {} = {}> =
 T extends ''  ? Ret :
 T extends `#${string}\n${infer Rest}` ? ParseProperties<Rest, Ret> :
 T extends `${infer Key}=${infer Rest}` ? ParseLine<Rest> extends [infer Value, infer Rest] ? ParseProperties<Rest, {[k in Key]:Trim<Value>} & Ret> : Ret : Ret;


type P1=ParseProperties<`hello=world\ngood=bye`>;
type P2=ParseProperties<`hello=world
#this is a comment
good=bye #what is this
#another
`>;

 type J1 = Join<['hi'],','>;
 type J2 = Join<['hi', 'there'], ','>;
 type J3 = Join<['hi', 'there', 'you', 'good'], ','>;
 type J4 = Join<[null, 'what']>;
 type J5 = Join<[null, 'what',null, 'more'], ','>;

type T1 = ParseLine<`hello\\nworld\nhow are\nyou`>;
type T2 = ParseLine<`hello\nhow are you`>;
type T3 = ParseLine<`hello\\nworld\\nhow are\nyou`>;
type T4 = ParseLine<`hello\\nworld\\nhow are\\nyou`>;

playground

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