Skip to content

void parameter type produced from generic inference doesn't allow skipping as argument #39600

Open
@maxim-grishaev

Description

@maxim-grishaev

TypeScript Version: 3.7.2, 3.9.6, 4.0.0-beta

Search Terms: overload, void, indexed void, implicit void

Code

class Hooks<TMap extends Record<string, any>> { 
    one(a: keyof TMap, b: void) { }
    two<K extends keyof TMap>(a: K, b: TMap[K]) { }
}
const h = new Hooks<{foo: void}>()
h.one('foo'); // OK
h.two('foo'); // Expected 2 arguments, but got 1.(2554)

Expected behavior: both methods can be called with only one argument

Actual behavior: TMap[K] that is resolved to void does not allow skip argument

Although, this one works as expected:

// v1 works
interface EvtMap {
    one: string;
    two: void;
}

const createMethod = <N extends keyof EvtMap>(eventName: N) =>
    (ctx: EvtMap[N]) => null;

createMethod('one')('');
createMethod('two')();

// v2 fails
interface EvtMap {
    one: string;
    two: void;
}

const createMethod = <EvtMap>() =>
    <N extends keyof EvtMap>(eventName: N, ctx: EvtMap[N]) => null;

createMethod<EvtMap>()('one', '');
createMethod<EvtMap>()('two');

// generic method fails
interface TMap { 
    foo: void
}
class Hooks { 
    one(a: keyof TMap, b: void) { }
    two<K extends keyof TMap>(a: K, b: TMap[K]) { }
}
const h = new Hooks()
h.one('foo'); // OK
h.two('foo'); // Expected 2 arguments, but got 1.(2554)

Playground Link:

Related Issues: Not found

My StackOverflow question

Rationale for the pattern: semi-dynamic event management engine. Example

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions