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

Overload on constants: type checking additional parameters #191

Closed
NoelAbrahams opened this issue Jul 22, 2014 · 4 comments
Closed

Overload on constants: type checking additional parameters #191

NoelAbrahams opened this issue Jul 22, 2014 · 4 comments
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@NoelAbrahams
Copy link

Hi, consider this bit of code:

class Bar {
    public bar: string;
}
interface IFoo {
    doFoo(type: any, bar: any): void;
    doFoo(type: "Quux", bar: Bar): string;
}

We use it like this:

var foo: IFoo;
var result:string = foo.doFoo("Quux", new Bar()); // fine

However, while still specifying "Quux", if we pass any type other than new Bar() for the second argument, the compiler falls back to the non-overloaded method:

// Error TS2011: Cannot convert 'void' to 'string'.
var result2: string = foo.doFoo("Quux", "bar");

I think this is a bit unfortunate. We are missing an opportunity to verify that the additional arguments also match the overloaded signature.

Ideally the following

foo.doFoo("Quux", "bar");

should generate error TS2082: Supplied parameters do not match any signature of call target

See further discussion on the old codeplex site.

@RyanCavanaugh
Copy link
Member

This behavior is really unfortunate/unexpected.

@jonathandturner and I talked about this for a long time trying to figure out what exactly the formal rule is. One complication is that we allow arbitrary intermixing of string constant overloads in any parameter position, so it's hard to write a rule that exactly encompasses what the user intent is with this rule.

@danielearwicker
Copy link

I just got surprised by this, but it turned out okay. Initially I designed an API so clients would say:

registry.add("editor", myEditor);

And found (as above) myEditor was not appropriately constrained by the specialization for "editor". To get around this I changed it to:

registry.kind("editor").add(myEditor);

In OO terms: return a "builder object" that accepts the remaining information, or a "fluent interface". (Or in much cooler FP terms: currying.)

Of course this is no good if you want to stick rigidly to describing some existing JS API, but you can provide it as a type-checkable alternative for TS clients.

This approach has another advantage that also worked well for me: suppose the old register.add function took a lot of other parameters (some optional). Every specialization would have to re-declare all those parameters. But by "currying" it, the specializations can become a lot simpler, e.g.

interface Registry {
    kind(kind: "editor"): Kind<Editor>;
}

The generic Kind<T> interface takes care of declaring add(v: T, ...) where ... is any number of optional extra parameters. So I can evolve those parameters without having to go around fixing all the specializations.

TL;DR: it was a surprise, but turned out not to be a problem in practise.

@mhegazy mhegazy added Fixed A PR has been merged for this issue and removed Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Feb 20, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Feb 20, 2016

With #6278 in place, you can omit the general signature, and the expected checks should take place. also as noted in #6746 (comment), doing so will restrict how the function can be called.

@mhegazy mhegazy closed this as completed Feb 20, 2016
@NoelAbrahams
Copy link
Author

This is great news. We've had to hack around this for a long time. I hope the fix makes it into a release soon. Thanks.

@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
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants