Skip to content

Broken keyof inferenceΒ #46870

@DScheglov

Description

@DScheglov

Bug Report

πŸ”Ž Search Terms

keyof

πŸ•— Version & Regression Information

  • This changed between versions 4.4.4 and 4.5.2

Also the bug was reproduced in the Playground with version 4.5.0-beta

⏯ Playground Link

Playground (v4.5.0-beta)

πŸ’» Code

import React from "react";

type SetState<S> = {
    (value: S): void;
    (reducer: (currentState: S) => S): void;
};

type StateManager<S> = {
    getState(): S;
    setState: SetState<S>;
    subscribe(listener: (value: S) => void): () => void;
};

type StateType<SM> = SM extends StateManager<infer S> ? S : never;

type KeyOfType<S extends {}, T> = {
    [P in keyof S]: S[P] extends T ? P : never;
}[keyof S];

export function useStateManager<S>({ getState, setState, subscribe }: StateManager<S>): [S, SetState<S>] {
    const [, next] = React.useReducer((v: number) => v + 1, 0);
    React.useEffect(() => subscribe(() => next()), []);

    return [getState(), setState];
}

export function useStateManagerFromContext<C extends {}, N extends KeyOfType<C, StateManager<any>>>(
    context: React.Context<C>,
    stateManagerName: N
) {
    const ctx: Pick<C, KeyOfType<C, StateManager<any>>> = React.useContext(context);
    return useStateManager<StateType<C[N]>>(ctx[stateManagerName]);
}

πŸ™ Actual behavior

The Error reported and compilation failed:

Errors in code
Argument of type 'C[N]' is not assignable to parameter of type 'StateManager<StateType<C[N]>>'.
  Type 'C[KeyOfType<C, StateManager<any>>]' is not assignable to type 'StateManager<StateType<C[N]>>'.
    Type 'C[C[keyof C] extends StateManager<any> ? keyof C : never]' is not assignable to type 'StateManager<StateType<C[N]>>'.
      Type 'C[keyof C]' is not assignable to type 'StateManager<StateType<C[N]>>'.
        Type 'C[string] | C[number] | C[symbol]' is not assignable to type 'StateManager<StateType<C[N]>>'.
          Type 'C[string]' is not assignable to type 'StateManager<StateType<C[N]>>'.

πŸ™‚ Expected behavior

No error reported as it works before, as instance in v4.4.4:

Playground (v4.4.4)

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions