Hi, i am trying to abstract my parsers a bit, and was hoping to write generic type/function that would allow to pass parser functions around...
function parseSome(state: ParserState, input: string): AstSome {...}
function parseOther(state: ParserState, input: string): AstOther {...}
function parseElse(state: ParserState, input: string): AstElse {...}
function parseDifferent(state: ParserState, input: string): AstDifferent {...}
// dozens of various "children" nodes around that have various types
type AaaChildren = (AstSome | AstOther | AstElse)[];
type BbbChildren = (AstOther | AstDifferent)[];
// etc.
interface AstAaa { type: 'aaa', children: AaaChildren }
interface AstBbb { type: 'bbb', children: BbbChildren }
// each of specific children can be identified by pre-defined constant keyword in input, e.g. "some", "other", "else", "different"
type ChildrenParsers<T> = { [key: string]: (parserState, someInput) => "one of T's alternatives" };
function parseChildren<T>(input: string, childrenParsers: ChildrenParsers<T>): "one of T's alternatives" {}
// usage attempt
const aaaNode = parseChildren<AaaChildren>(input, {"some": parseSome, "other": parseOther, "else": parseElse});
const bbbNode = parseChildren<BbbChildren>(input, {"other": parseOther, "different": parseDifferent});
Did i approach this in incorrect way? How could i declare that one of specific sub-types of T is to be returned by a child parser?