strblr
strblr

Reputation: 950

Why can't TypeScript infer this generic type?

I have the following code :

abstract class Parser<Value, Context> {
  abstract exec(
    options: ParseOptions<Context>,
    internals: Internals
  ): Match<Value> | null;
}

class LiteralParser<
  Value extends string | undefined,
  Context
> extends Parser<Value, Context> {
  readonly literal: string;
  readonly emit: boolean;

  constructor(literal: string, emit: boolean) {
    super();
    this.literal = literal;
    this.emit = emit;
  }

  exec(options: ParseOptions<any>, internals: Internals) {
    // other stuff
    return null;
  }
}

But when trying to infer the Context type from a LiteralParser type, it fails :

type Extr<T> = T extends Parser<any, infer C> ? C : never;

type A = Extr<LiteralParser<string, unknown>>; // "any", should be "unknown"

But it gets weirder : When removing the abstract method exec from Parser, it works :

type Extr<T> = T extends Parser<any, infer C> ? C : never;

type A = Extr<LiteralParser<string, unknown>>; // "unknown"

Link to playground

What is going on ? Thank you.

Upvotes: 0

Views: 51

Answers (1)

Vojtěch Strnad
Vojtěch Strnad

Reputation: 3185

I'm not exactly sure why, but the any type comes from your definition of exec:

exec(options: ParseOptions<any>, internals: Internals)

When you use the original type –

exec(options: ParseOptions<Context>, internals: Internals)

– everything works.

Playground link

Upvotes: 1

Related Questions