Skip to content

Function not callable when using a generic type parameter and union typesΒ #50182

Closed
@lo1tuma

Description

@lo1tuma

Bug Report

πŸ”Ž Search Terms

  • This expression is not callable.
  • TS2349
  • generic
  • union type

πŸ•— Version & Regression Information

Problem happens in all recent versions of typescript.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

interface EventEmitter<Mapping> {
    on<EventName extends keyof Mapping>(eventName: EventName): void;
}

interface PayloadA {
    readonly foo: number;
    readonly bar: string;
}

interface PayloadB {
    readonly foo: number;
    readonly baz: boolean;
}

type EmitterA = EventEmitter<PayloadA>;
type EmitterB = EventEmitter<PayloadB>;

interface ModuleA {
    readonly type: 'a';
    readonly on: EmitterA['on'];
}

interface ModuleB {
    readonly type: 'b';
    readonly on: EmitterB['on'];
}

function doStuff(mod: ModuleA | ModuleB): void {
    if (mod.type === 'a') {
      mod.on('foo'); // works
    } else {
      mod.on('foo'); // works
    }
    mod.on('foo'); // doesn’t work
}

πŸ™ Actual behavior

The following error is reported when calling mod.on('foo'); without narrowing its exact type:

This expression is not callable.
  Each member of the union type '(<EventName extends keyof PayloadA>(eventName: EventName) => void) | (<EventName extends keyof PayloadB>(eventName: EventName) => void)' has signatures, but none of those signatures are compatible with each other.

πŸ™‚ Expected behavior

Since mod.on('foo') works in all possible branches when narrowing down the type I would expect it to also work without branching and narrowing.

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