Skip to content

Function signature overloading turns off return type checking inside the function? #44262

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
Zodiase opened this issue May 26, 2021 · 2 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@Zodiase
Copy link

Zodiase commented May 26, 2021

Bug Report

🔎 Search Terms

"typescript overloading doesn't check return type"

🕗 Version & Regression Information

[email protected] is my current version. I've only noticed the problem today.

⏯ Playground Link

Playground link with relevant code

💻 Code

class Foo {
  func2<T extends string | number>(
    param1: T
  ): T extends string ? number[] : number {
    if (typeof param1 === 'string') {
      return 1;
    }
  }

  func(param1: string, param2: number): number; // overload 1
  func(param1: string, param2: string): number[]; // overload 2
  func(param1: string, param2: number | string): number | number[] {
    if (typeof param2 === 'string') {
      return 1; // Doesn't match overload signature 2.
    }
  }
}

🙁 Actual behavior

image

With func2, the return type error is very helpful especially in writing large functions with many branches.
With func, I have more or less the same need for dynamic return type (someone else wrote this unfortunate code and I'm just trying to type it), but TypeScript is unable to warn me that when param2 is a string, I'm actually returning the wrong type.

I read #13225 and got a sense that in a function with overloading, TS only checks if the return type satisfies the return type of the implementation function, not any of the overloads, even though TS only recognizes the overload signatures when the function is called. I've tested this assumption with this slightly altered snippet:
image

This looks plenty scary to me thinking that by using function overloading, I lost a lot of protection from TS inside the function.

🙂 Expected behavior

Just like what happens in func2, in func it's still possible to statically analyze which overloading signature the returning line is in, and an error is provided about the incorrect return type.

@DanielRosenwasser DanielRosenwasser added the Working as Intended The behavior described is the intended behavior; this is not a bug label May 26, 2021
@DanielRosenwasser
Copy link
Member

Bodies of functions are only checked against their implementation signatures. Implementation signatures are unsafely checked against overloads by checking whether their return types are bidirectionally compatible. It's "working as intended" but it's a bit of a design limitation because doing anything better would require some sort of deeper higher-level reasoning that we're not yet equipped for.

@Zodiase
Copy link
Author

Zodiase commented May 26, 2021

Cool. Thanks for the explanation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants