Skip to content

Function argument types only inferred for mapped function with the maximum number of arguments #17391

@grind086

Description

@grind086

TypeScript Version: 2.4.1

Code

interface MyEvents {
    'zero'  : () => void;
    'one'   : (arg1: string) => void;
    'two'   : (arg1: string, arg2: string) => void;
    'three' : (arg1: string, arg2: string, arg3: string) => void;
    'four'  : (arg1: string, arg2: string, arg3: string, arg4: string) => void;
}

interface MyEmitter<T> {
    on<K extends keyof T>(event: K, fn: T[K]): this;
    once<K extends keyof T>(event: K, fn: T[K]): this;
}

declare const myEmitter: MyEmitter<MyEvents>;

myEmitter.on('zero'  , () => {});
myEmitter.on('one'   , (arg1) => {});
myEmitter.on('two'   , (arg1, arg2) => {});
myEmitter.on('three' , (arg1, arg2, arg3) => {});
myEmitter.on('four'  , (arg1, arg2, arg3, arg4) => {});

Expected behavior:
Types are inferred for all event callback arguments.

Actual behavior:
Types are inferred only for the callback arguments of the event 'four'. If 'four' is removed from MyEvents, then only the callback arguments for 'three' are inferred. If 'three' is removed, then only the arguments for 'two' are inferred. etc.

The order of properties on MyEvents has no effect, and if there are multiple events with the maximum number of arguments they are all inferred correctly.

EDIT: I just noticed adding another function with the same number of arguments, but different types also prevents arguments from being inferred, so this is probably an issue with merging the type signatures. Interestingly IntelliSense (both in VSCode, and the online playground) can still infer the proper types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions