Skip to content

Generics, overloaded functions, and objects interact inconsistently #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
georgewfraser opened this issue Jul 21, 2014 · 4 comments · Fixed by #196
Closed

Generics, overloaded functions, and objects interact inconsistently #167

georgewfraser opened this issue Jul 21, 2014 · 4 comments · Fixed by #196
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Spec Issues related to the TypeScript language specification

Comments

@georgewfraser
Copy link

Type inference exhibits strange behavior when you have an overloaded function with a generic that takes an object as an argument:

// A function that extracts the values from an object
declare function values<T>(object: { [key: number]: T }): T[];
declare function values<T>(object: { [key: string]: T }): T[];

// A type with a member called 'a'
interface MemberA {
    a: number;
}

// OK
declare var numberObject: { [key: number]: MemberA };
values(numberObject).map(value => value.a);

// Error, infers value : {}
declare var stringObject: { [key: string]: MemberA };
values(stringObject).map(value => value.a);

It seems to be just choosing the first overload.

@ahejlsberg
Copy link
Member

That is odd, I agree. The problem appears to be the way in which type inference interacts with assignability and overload resolution. We make inferences from index signatures only when the index signature kinds match (section 3.8.6 in spec), but we consider both string and numeric index signatures to be assignable to numeric index signatures with compatible types (section 3.8.4 in spec). The net outcome is that in your example that generates an error, we infer {} for T in the first overload (because the signature kinds are different) and then we subsequently pick the first overload because [key: string]: MemberA is assignable to [key: number]: T.

I think we need to change the inference rules to allow inferences to be made from both string and numeric index signatures to index signatures such that inference and assignability line up.

@JsonFreeman
Copy link
Contributor

Yes, I agree with @ahejlsberg's solution here. In general, the type argument inference relation should mirror the assignability relation as closely as possible.

ahejlsberg added a commit that referenced this issue Jul 22, 2014
Type inference now supports inferring from string index signatures to numeric index signatures.
Fixes #167.
@ahejlsberg ahejlsberg reopened this Jul 22, 2014
@ahejlsberg
Copy link
Member

Changing to spec issue. Section 3.8.6 needs to be updated to reflect that we now make inferences from both string and numeric index signatures to numeric index signatures.

@ahejlsberg ahejlsberg self-assigned this Jul 22, 2014
@ahejlsberg
Copy link
Member

@georgewfraser Thanks for reporting. Fixed in the new compiler.

@sophiajt sophiajt added this to the TypeScript 1.1 milestone Jul 22, 2014
@sophiajt sophiajt reopened this Jul 22, 2014
@RyanCavanaugh RyanCavanaugh added the Fixed A PR has been merged for this issue label Sep 11, 2014
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Spec Issues related to the TypeScript language specification
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants