Skip to content

Higher order function inference breaks with multiple overloads #30369

@OliverJAsh

Description

@OliverJAsh

TypeScript Version: 3.3.3333, 3.4.0-dev.20190313

Search Terms: higher order function generic param inference any reselect

Code

This is an issue I found whilst using the popular Reselect library, however I believe it is a bug with TypeScript rather than the type definitions. Here is a minimal repro.

type Selector<S, R> = (state: S) => R;
type ParametricSelector<S, P, R> = (state: S, props: P) => R;

// Comment out this overload and things work as expected
declare function createSelector<S, R1, R2>(
    selector1: Selector<S, R1>,
    selector2: Selector<S, R2>,
): void;
declare function createSelector<S, P, R1, R2>(
    selector1: ParametricSelector<S, P, R1>,
    selector2: ParametricSelector<S, P, R2>,
): void;

type Props = { foo: 1 };
createSelector(
    (
        // Expected `state` param type to be inferred as `{}` (fallback)
        // Actual type: `any`
        state,
        props: Props,
    ) => props.foo,

    (
        // Expected `state` param type to be inferred as `{}` (fallback)
        // Actual type: `any`
        state,

        // Expected `props` param type to be inferred as `Props`
        // Actual type: `any`
        props,
    ) => props.foo,
);

// Workaround: annotate first function's state param
type State = {};
createSelector(
    (state: State, props: Props) => props.foo,
    (state, props) => props.foo,
);

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions