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

Function Overload Parameter and Return Mismatch #23861

Closed
MrDesjardins opened this issue May 3, 2018 · 4 comments
Closed

Function Overload Parameter and Return Mismatch #23861

MrDesjardins opened this issue May 3, 2018 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@MrDesjardins
Copy link

TypeScript Version: 2.9.0-dev.20180503
Search Terms: overload, function, parameter, return

Code

function funct5(param1: boolean): string;
function funct5(param1: Date): number;
function funct5(param1: boolean | Date): string | number {
        if (typeof param1 === "boolean") {
            return 1; // Expected to have a TS error saying that only a string is valid
        } else {
            return 0;
        }
}

Expected behavior:
Since the param1 is narrowed down to be a boolean, only a single overload is valid (the first one that returns a string). However, I can return a number which should only be valid if the param1 is a Date.

Actual behavior:
I was expecting TypeScript to notify me that the return type was invalid because of the type of the param1.

Playground Link: Link

Related Issues:

@ghost
Copy link

ghost commented May 3, 2018

Implementation of overloads is unsafe -- only the version of the function with a body is actually checked. So it's checked as if you didn't write the overloads above it, but called as if you had only written the overload signatures.

@ghost ghost added the Question An issue which isn't directly actionable in code label May 3, 2018
@jcalz
Copy link
Contributor

jcalz commented May 3, 2018

Disclaimer: I am not a TypeScript language designer/maintainer.

This is intended behavior, although it might not be completely clear from the handbook documentation or the spec, and doesn't seem to be directly addressed in the FAQ.

The stuff you probably know: for overloaded functions there are one or more overload signatures (the ones that have no implementation after it), and a single implementation signature (the one with the implementation after it). The implementation signature is required to be at least as general as all the overload signatures (or, from the other direction, each overload signature must be at least as specific as the implementation signature).

What you might not realize: The overload signatures only constrain what the caller of the function can do, while the implementation signature only constrains what the implementation of the function can do. The caller doesn't see the implementation signature, and the implementation doesn't see the overload signatures.

So in your case the compiler doesn't complain that the return value for a boolean input is a number, since the return type of the implementation signature is string | number, and number is compatible with string | number. Only the overload signatures care about the boolean-in-string-out constraint, which means only the function caller will expect this. As you have discovered, this is not fully type-safe. I imagine that this was chosen for practical reasons (limits the work that the type checker needs to perform while still giving some semblance of type safety) but I can't speak authoritatively on that.

Hope that makes sense.

Related issues: #22609

@MrDesjardins
Copy link
Author

Thank you both of you.

I understand the challenge with more complex overloading scenario which TypeScript may have a hard time to analyze every situation, but it seems rational to believe that as a developer if I provide the type for a specific disposition of type that not only the consumer is leveraging that typing but also the maintainer of the function. The actual state of overloading is precarious leaving the doubt that we have safety mechanism because we are explicit when in fact an error can slip easily. Stil, better than nothing because the consumer of the library is getting an additional value than just the union parameters and returns.

Thank you for finding the related issue. I couldn't see it myself. Hopefully, something will improve around that feature.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants