Microsoft/TypeScript

Narrowing `this` using custom type predicate affected by TS 5.0

Open

#53 436 ouverte le 22 mars 2023

Voir sur GitHub
 (5 commentaires) (1 réaction) (0 assignés)TypeScript (6 726 forks)batch import
BugDomain: This-TypingHelp Wanted

Métriques du dépôt

Stars
 (48 455 stars)
Métriques de merge PR
 (Merge moyen 6j 17h) (9 PRs mergées en 30 j)

Description

Bug Report

🔎 Search Terms

narrowing this predicate

🕗 Version & Regression Information

  • This changed between versions 4.9 and 5.0

⏯ Playground Link

Playground link with relevant code

💻 Code

interface Typestate<TContext extends object> {
  value: string;
  context: TContext;
}

interface State<TContext extends object, TState extends Typestate<TContext>> {
  value: TState["value"];
  context: TContext;
  matches: <TSV extends TState["value"]>(
    value: TSV
  ) => this is TState extends {
    value: TSV;
  }
    ? TState & {
        value: TSV;
      }
    : never;
}

interface Machine<TContext extends object, TState extends Typestate<TContext>> {
  initialState: State<TContext, TState>;
}

export declare function createMachine<
  TContext extends object,
  TState extends Typestate<TContext> = {
    value: any;
    context: TContext;
  }
>(): Machine<TContext, TState>;

const machine = createMachine<{ count: number }>();
const state = machine.initialState;

if (state.matches("idle")) {
  ((_accept: number) => {})(state.context.count);
  // @ts-expect-error
  ((_accept: string) => {})(state.context.count);
} else if (state.matches("latest")) {
  ((_accept: number) => {})(state.context.count);
  // @ts-expect-error
  ((_accept: string) => {})(state.context.count);
}

🙁 Actual behavior

state gets narrowed down to never in the else branch

🙂 Expected behavior

state to only get narrowed down to the appropriate value within the if branch

cc @ahejlsberg

Guide contributeur