I'm trying to create some extensible query parser for my project. It should parse incoming query string and return typed object. Also It should get typesd object and return string.
Lets imagine that I have my parametrized handler QueryParamHandler for each single parameter which is
class QueryParamHandler<T> {
parse(v: string): T;
stringify(v: T): string;
}
Then I have set of handlers for each type I want
const stringParser: QueryParamHandler<string> = ...;
const numberParser: QueryParamHandler<number> = ...;
const booleanParser: QueryParamHandler<boolean> = ...;
const dateParser: QueryParamHandler<Date> = ...;
now I want to create wrapper that can parse whole set of parameters depending on set of parsers that I provide in constructor
class MyCoolHandler<...> {
constructor<TP>(handlers: TP extends Record<string, QueryParamHandler<any>>) {}
parse(query: string): TV? {}
stringify(vals: TV?): string {}
}
so how should I describe type TV (where all values can be undefined) to force typescript to check it based on passed handlers? I will describe desired behavior in following example:
const handler = new MyCoolHandler({ str: stringParser, from: dateParser });
handler.stringify({}); // ok
handler.stringify({ str: 'qqq' }); // ok
handler.stringify({ numb: 3 }); // TS error, `numb` key is not allowed here
handler.stringify({ from: 'qq' }); // TS error, `from` key should be Date type
const params = handler.parse('str=&from=2021-09-07')
console.log(params.str) // ''
console.log(params.numb) // TS error, params doesn't have 'numb' key
TPandTV. Please get rid of syntax errors