Skip to content
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

Another strange behavior with type inference #1947

Closed
fdecampredon opened this issue Feb 5, 2015 · 5 comments
Closed

Another strange behavior with type inference #1947

fdecampredon opened this issue Feb 5, 2015 · 5 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@fdecampredon
Copy link

I'm sorry to bother you again but this one seems pretty much strange:

interface Something {
    prop?: string ;
}


interface SomethingElse extends Something {
    prop1: string;
}

class Test<T> {
    constructor(props: T) {

    }
}

class A extends Test<SomethingElse> {

}

declare function myFunc<T>(type: { new(props: T): Test<T> }, props: T): Test<T>
declare function myFunc(type:string, test: Something): string;

var t: any;
var hello = myFunc(A, { prop: '', prop1: t}); // Argument of type 'typeof A' is not assignable to parameter of type 'string'
  • Firstly the call to myFunc is perfectly valid with the first overload and not with the second one, but the compiler still pick the second.
  • Secondly event in case we had called myFunc(A, { prop: ''}) the fact that the compiler pick the second overload make the error hard to understand for the developer.
@fdecampredon fdecampredon changed the title Another strange behavior with type inference an union Another strange behavior with type inference Feb 5, 2015
@ahejlsberg
Copy link
Member

The issue here is that neither { prop?: string; prop1: string; } nor { prop: string; prop1: any; } is a subtype of the other--and it's not 100% clear that one of them should be. So, because we can't find a single type that is a supertype of all others, type inference fails for the first overload. The second overload doesn't work either, so the compiler now has to report an error. As a matter of policy, we pick the last overload to use in error reporting because it is generally the most permissive (the "catch all", so to speak).

You could argue we should try harder to find a suitable type argument for the first overload, but we have to balance that against trying too hard and making a bad inference instead of giving an error. This one is right one the edge, but I'm not sure what we could change to do better.

@fdecampredon
Copy link
Author

As a matter of policy, we pick the last overload to use in error reporting because it is generally the most permissive (the "catch all", so to speak).

No in this example the overload with string is always the one picked, even if I switch overload place

@Ciantic
Copy link

Ciantic commented Apr 8, 2015

I'll say it here too, why not add a new syntax to say which one is used for type inference:

declare function myFunc<T>(type: { new(props: T): Test<T^> }, props: T): Test<T>

This little ^ I smuggled there would say that it's more important.

@mhegazy mhegazy added the In Discussion Not yet reached consensus label Dec 9, 2015
@RyanCavanaugh RyanCavanaugh added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. and removed In Discussion Not yet reached consensus labels Jan 4, 2016
@RyanCavanaugh
Copy link
Member

This needs a more thorough explanation of the proposed fix before we can look at it.

@RyanCavanaugh
Copy link
Member

This call succeeds now 🤷‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants