Skip to content

Incorrect overload is used for composed function inside pipe #25637

Closed
@OliverJAsh

Description

@OliverJAsh

TypeScript Version: 2.9.2

Search Terms: generic function pipe contextual type wrong overload

Code

These examples are stripped down versions of Node's parse function in the querystring module and Lodash's values and fromPairs functions.

These are issues we ran into when trying to use these functions with a pipe function.

declare function pipe<A, B, C>(ab: (a: A) => B, bc: (b: B) => C): (a: A) => C;

{
    type ParsedUrlQuery = { [index: string]: string };
    declare function parsedUrlQueryString(str: string): ParsedUrlQuery;
    declare function parsedUrlQueryString<T extends {}>(str: string): T;

    declare const stringToString: (s: string) => string;

    // $ExpectType (a: string) => ParsedUrlQuery
    // but got (a: string) => {}
    // Note: if we comment out the last overload for `parsedUrlQueryString`, we get the expected
    // type.
    const fn = pipe(
        stringToString,
        parsedUrlQueryString,
    );
}

{
    declare function values<T>(object: { [index: string]: T } | null | undefined): T[];
    declare function values<T extends object>(object: T | null | undefined): Array<T[keyof T]>;
    declare function values(object: any): any[];

    declare const stringDictToStringDict: (
        sd: { [index: string]: string },
    ) => { [index: string]: string };

    // $ExpectType (a: { [index: string]: string; }) => string[]
    // but got (a: { [index: string]: string; }) => any[]
    // Note: if we comment out the last two overloads for `values`, we get the expected type.
    const fn = pipe(
        stringDictToStringDict,
        values,
    );
}

{
    declare function fromPairs<T>(pairs: [string, T][] | null | undefined): { [index: string]: T };
    declare function fromPairs(pairs: any[][] | null | undefined): { [index: string]: any };

    // $ExpectType (a: {}) => { [index: string]: number; }
    // but got (a: {}) => { [index: string]: any; }
    // Note: if we comment out the last overload for `fromPairs`, we get the expected type.
    const fn = pipe(
        ({  }: {}): [string, number][] => [['foo', 1]],
        fromPairs,
    );
}

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