Skip to content

Interface and type being treated differently in overload resolution #18779

Closed
@Ghabriel

Description

@Ghabriel

TypeScript Version: 2.5.2

Code

type Map<T> = {[key: string]: T};

type Callback<T> = (key: string, value: T) => void;

declare function foo<T>(obj: Map<T>, callback: Callback<T>): void;
declare function foo<C,T>(obj: {[P in keyof C]: T}, callback: Callback<T>): void;

interface SomeInterface {
    a: number;
    b: number;
}

type SomeType = {
    a: number;
    b: number;
}

let x: SomeInterface = {
    a: 42,
    b: 60
};

let y: SomeType = x;

foo(x, (key, value) => console.log(key, value));
foo(y, (key, value) => console.log(key, value));

Expected behavior:
Both calls to foo should use the first overload (and deduce T as number).

Actual behavior:
The first call to foo uses the second overload and both C and T are deduced as {} (i.e foo<{}, {}>). If the second overload is removed, the program fails to compile:

TS2345: Argument of type 'SomeInterface' is not assignable to parameter of type 'Map<{}>'.
  Index signature is missing in type 'SomeInterface'.

(and other 2 errors since key and value would implicitly become any)

This might be some intended difference between interface and type that I didn't see documented anywhere, but I'm posting this here just to be sure.

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