Skip to content

Better type inference for choice()? #87

@KillyMXI

Description

@KillyMXI

Is it possible for choice(pa, pb, pc) to infer a parser of TA | TB | TC as a result?

export function choice<TToken,TOptions,TValue> (
  ...ps: Parser<TToken,TOptions,TValue>[]
): Parser<TToken,TOptions,TValue>;

Currently it requires a type hint - cast at least on of arguments to more common type.

First idea - change it like following:

export function choice<TToken,TOptions,TValue,TParsers extends Parser<TToken,TOptions,TValue>[]> (
  ...ps: TParsers
): Parser<TToken,TOptions,TValue>;

This doesn't work. I want to infer types from arguments, but now arguments are typed based on generic types.

Second idea:

export function choice<
  TToken,
  TOptions,
  TParser extends Parser<TToken,TOptions,TValue1>,
  TValue1 = TParser extends Parser<TToken,TOptions,infer T> ? T : never
> (
  ...ps: TParser[]
): Parser<TToken,TOptions,TValue1>;

This fails on a call without arguments (and I skipped testing it for more than 1 argument).
Maybe it would be possible to fix, but then I come to realization that it is not clear how this should be written for the Matcher overload.

My next thought:

I have an array of functions. I can get return type of a function with ReturnType<> utility if needed. Then I would need some contraption to turn an array into a unity type.
If there is a solution - it might even work for Matcher overload. And the case of an empty array would be a step in reduction.

Will get back to this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions