Skip to content

v4.0.x -> v4.1.1-rc change in overload selection #41563

Closed
@tchetwin

Description

@tchetwin

TypeScript Version: 4.1.0-dev.20201029, 4.1.1-rc

Search Terms: overload

Code

import { promisify } from "util";

// These are components of @types/xml2js@0.4.5
export interface convertableToString {
    toString(): string;
}
declare class Parser {
    parseString(str: convertableToString, cb?: Function): void;
}

const xmlParser = new Parser();
const parseString = xmlParser.parseString.bind(xmlParser);
const parseStringP = promisify(parseString); // <--- interested in overload selection from this line

parseStringP("abc");
//           ^--- error surfaces here

Expected behavior:

No error. This overload is selected from promisify:

(alias) promisify<convertableToString, unknown>(fn: (arg1: convertableToString, callback: (err: any, result: unknown) => void) => void): (arg1: convertableToString) => Promise<...> (+13 overloads)

Actual behavior:

Expected 0 arguments, but got 1. (2554) (on the argument to parseStringP). This overload is selected from promisify:

(alias) promisify<unknown>(fn: (callback: (err: any, result: unknown) => void) => void): () => Promise<unknown> (+13 overloads)

Notes:

Overloads from unpkg:

interface CustomPromisifyLegacy<TCustom extends Function> extends Function {
    __promisify__: TCustom;
}
interface CustomPromisifySymbol<TCustom extends Function> extends Function {
    [promisify.custom]: TCustom;
}
type CustomPromisify<TCustom extends Function> = CustomPromisifySymbol<TCustom> | CustomPromisifyLegacy<TCustom>;

function promisify<TCustom extends Function>(fn: CustomPromisify<TCustom>): TCustom;
function promisify<TResult>(fn: (callback: (err: any, result: TResult) => void) => void): () => Promise<TResult>;
function promisify(fn: (callback: (err?: any) => void) => void): () => Promise<void>;
function promisify<T1, TResult>(fn: (arg1: T1, callback: (err: any, result: TResult) => void) => void): (arg1: T1) => Promise<TResult>;
function promisify<T1>(fn: (arg1: T1, callback: (err?: any) => void) => void): (arg1: T1) => Promise<void>;
function promisify<T1, T2, TResult>(fn: (arg1: T1, arg2: T2, callback: (err: any, result: TResult) => void) => void): (arg1: T1, arg2: T2) => Promise<TResult>;
function promisify<T1, T2>(fn: (arg1: T1, arg2: T2, callback: (err?: any) => void) => void): (arg1: T1, arg2: T2) => Promise<void>;
// removed overloads with 3, 4 & 5 template parameters for brevity
function promisify(fn: Function): Function;

Playground Links:

4.1.0-beta ✔️
4.1.0-dev.20201028 ✔️
4.1.0-dev.20201029
4.1.1-rc
4.2.0-dev.20201112

Related Issues:

#41099 - Similar looking but the version introducing the regression doesn't align.
#41359 (comment) - Previously reported in this Issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    Breaking ChangeWould introduce errors in existing codeRescheduledThis issue was previously scheduled to an earlier milestone

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions