Parser Combinator as list
Hi there.
The typescript typings of the then combinator allow to pass up to four parsers to the combinator.
Is it possible to pass either 5 or pass a list of parsers to a then method?
I guess it is a limitation of Typescript to have not the possibility to define Arrays with generics in a specific order. So the easiest is probably to define the following in your d.ts file:
import { ImplicitParjser, ParjsCombinator } from 'parjs'
type ImplicitParjserArray<B, C, D, E, F, G> =
[ImplicitParjser<B>, ImplicitParjser<C>, ImplicitParjser<D>, ImplicitParjser<E>, ImplicitParjser<F>] |
[ImplicitParjser<B>, ImplicitParjser<C>, ImplicitParjser<D>, ImplicitParjser<E>, ImplicitParjser<F>, ImplicitParjser<G>]
declare module 'parjs/combinators' {
export function then<A, B, C, D, E, F, G> (
...parsers: ImplicitParjserArray<B, C, D, E, F, G>
)
: ParjsCombinator<A, [A, B, C, D, E, F, G]>
}
With TypeScript 4.x, variadic tuple is now available, so the above can simplify to the following:
import { ImplicitParjser, ParjsCombinator } from "parjs";
declare module "parjs/combinators" {
export function then<T, U extends any[]>(
...parsers: { [key in keyof U]: ImplicitParjser<U[key]> }
): ParjsCombinator<T, [T, ...U]>;
}
Explanation of what's going on here:
- We the
thento have a generic parameterUthat must be an array type. This construct in TypeScript means a tuple type, such as[string, number, string]is also allowed. - We specify that the type of the parsers, which make up the variadic arguments (
...parsers), are the correspondingImplicitParsertype of each of the tuple's elements, using the mapped tuple type expression ({ [key in keyof U]: ImplicitParjser<U[key]> }) to perform such a type mapping. - The return type of this combinator is the concatenation of the source type
Tand the variadic parsers' result types. Importantly, the variadic result must be spread ([T, ...U]) and not nested ([T, U]).
Example:
// p is of type Parjser<[string, number, string, number, string, number]>
const p = string("x").pipe(
then(float(), string("x"), float(), string("x"), float())
);
A PR would be possible but it would cause a breaking change because of a breaking change in the dependency (requires an upgrade to TypeScript 4).
Nice, I wonder if @GregRos has a list of features he want's to put into version 1.0.0 of parjs
Looks like @GregRos hasn't been around on GitHub a couple of months. I really like this package and would love to see it grow. I wonder what we can do.
I've already locally made a few extensions. Perhaps I could publish some of these extensions in a separate NPM package that can serve as a staging area, perhaps even requiring TS 4.x for such extensions? What do you think @valoricDe?
I think we could ask @GregRos if he gives you maintainer rights. I'm not actively using this package anymore but I think it is really helpful if regexp is to limited. If @GregRos is not answering I would fork this repo, publish as parjs2 and describe in the readme that parjs is not maintained anymore. Not ideal but maybe better than alternatives?
It's been 20 days since our last conversation and it appears that @GregRos is unfortunately not available to answer. @valoricDe would you like to fork this repo or let me do it?
Hi SoulCodes, sry I wrote my text a bit ambiguous. I actually meant: If I were you I would fork it then.
Thank you! I'll definitely do this as part of a future upgrade.
Looks like the type is correctly inferred now on the current master branch:
Please let me know if you think I'm wrong. Maybe this can be closed as completed?