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

Improve type inference on parameter types and return types of overload class methods implementation. #46132

Closed
tychenjiajun opened this issue Sep 29, 2021 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@tychenjiajun
Copy link

Suggestion

πŸ” Search Terms

class\implements\type inference\overload\class methods

βœ… Viability Checklist

My suggestion meets these guidelines:

  • [] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [*] This wouldn't change the runtime behavior of existing JavaScript code
  • [*] This could be implemented without emitting different JS based on the types of the expressions
  • [*] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • [*] This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Read the codes and comments below.

πŸ“ƒ Motivating Example

class Foo {
    foo(a: number): 1;
    foo(a: string): 2;
    foo(a: boolean): 3;
    foo(a: boolean | number | string): 1 | 2 | 3 {
        if (typeof a === 'number') return 1;
        if (typeof a === 'string') return 2;
        return 3;
    }
}

interface IFoo {
    foo<T extends 1>(a: number): T;
    foo<T extends 2>(a: string): T;
    foo<T extends 3>(a: boolean): T;
}

type F = {
    <T extends 1>(a: number): T;
    <T extends 2>(a: string): T;
    <T extends 3>(a: boolean): T;
}

class Bar2 implements IFoo {
    foo(a) { // error here: ts 7006. expected to be number | string | boolean
        if (typeof a === 'number') return 1;
        if (typeof a === 'string') return 2;
        return 3;
    }
}

class Bar implements IFoo {
    foo(a: number | string | boolean) {
        if (typeof a === 'number') return 1;
        else if (typeof a === 'string') return 2;
        else return 3;
    }
}

class Baz {
    foo: F = (a: any) => {
        if (typeof a === 'number') return 1;
        if (typeof a === 'string') return 2;
        return 3;
    }
}

new Foo().foo(1); // infer as 1
new Baz().foo('1'); // infer as 2;
new Bar().foo(true) // infer as 1 | 2 | 3, expected to be 3;

πŸ’» Use Cases

Some request/fetch library, return specific type based on path or parameters.

Maybe releated to #14107 #22609 #28172 #25352 #14515

@MartinJohns
Copy link
Contributor

Playground link...

@sandersn
Copy link
Member

sandersn commented Oct 7, 2021

The suggestion to change parameter type inference as in Bar2.foo is a duplicate of #32082 (and all the issues which that issue links to).
The suggestion to change return type inference is similar, except that it would also need the overloads to be inherited in addition to the signature.

I'd recommend adding the latter suggestion to the discussion at #32082.

@sandersn sandersn closed this as completed Oct 7, 2021
@sandersn sandersn added the Duplicate An existing issue was already created label Oct 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants