Skip to content

Function Overload Parameter and Return Mismatch #23861

Closed
@MrDesjardins

Description

@MrDesjardins

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:

Activity

ghost

ghost commented on May 3, 2018

@ghost

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 added
QuestionAn issue which isn't directly actionable in code
on May 3, 2018
jcalz

jcalz commented on May 3, 2018

@jcalz
Contributor

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

MrDesjardins commented on May 3, 2018

@MrDesjardins
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

typescript-bot commented on May 18, 2018

@typescript-bot
Collaborator

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

locked and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jcalz@MrDesjardins@typescript-bot

        Issue actions

          Function Overload Parameter and Return Mismatch · Issue #23861 · microsoft/TypeScript