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

TypeScript unable to infer types properly between interfaces and overloaded methods. #43643

Open
benlesh opened this issue Apr 12, 2021 · 2 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@benlesh
Copy link

benlesh commented Apr 12, 2021

Bug Report

In all versions of TS I can find, there's no way to mark certain call patterns of a method as deprecated while maintaining inference with certain interfaces. If an interface is split out into different overloads so certain overloads can be deprecated, then it breaks inference in some cases.

🔎 Search Terms

I'm not sure what to search for here. Interfaces?

🕗 Version & Regression Information

  • All versions

⏯ Playground Link

Playground link with relevant code

💻 Code

interface Observer<T> {
    next(value: T): void;
    error(error: any): void;
    complete(): void;
}

interface Unsubscribable {
    unsubscribe(): void;
}

interface Subscribable<T> {
    subscribe(observer?: Partial<Observer<T>>): Unsubscribable;
}

class Observable<T> implements Subscribable<T> {
    /////////////////////////////////////////
    // Valid call pattern
    /////////////////////////////////////////
    subscribe(observerOrNext?: Partial<Observer<T>> | ((value: T) => void)): Unsubscribable;


    //////////////////////////////////////////
    // Deprecated call patterns
    //////////////////////////////////////////
    /**
     * @deprecated This call pattern is going away
     */
    subscribe(next: null | undefined, error: null | undefined, complete: () => void): Unsubscribable;
    /**
     * @deprecated This call pattern is going away
     */
    subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Unsubscribable;
    /**
     * @deprecated This call pattern is going away
     */
    subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Unsubscribable;
    /**
     * @deprecated This call pattern is going away
     */
    subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Unsubscribable;


    ////////////////////////////////////////////
    // Impl
    ////////////////////////////////////////////
    subscribe(...args: any[]): Unsubscribable {
        return {
            unsubscribe() {}
        };
    }
}


function somethingThatTakesSubscribable<T>(arg: Subscribable<T>): T {
    return null!;
}

/////////////////////////////////////
// Our failed expectation here
// (it's unknown)
/////////////////////////////////////
const result = somethingThatTakesSubscribable(new Observable<number>()); // $ExpectType number

🙁 Actual behavior

result is unknown above.

🙂 Expected behavior

result would be number.

@DanielRosenwasser DanielRosenwasser added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript labels Apr 12, 2021
@benlesh
Copy link
Author

benlesh commented Apr 12, 2021

@DanielRosenwasser I'm not sure if the Needs Proposal means I'm supposed to propose a solution, or there just needs to be some discussion on your team?

@DanielRosenwasser
Copy link
Member

It's either - I'm going to try to discuss this a bit on our side, but I don't know if we have a solution.

benlesh added a commit to benlesh/angular that referenced this issue Apr 13, 2021
Adds a fix to make sure that RxJS v7 Observable is compatible with AsyncPipe. This is a typings-only change.
For more information see: microsoft/TypeScript#43643
mhevery pushed a commit to angular/angular that referenced this issue May 4, 2021
Adds a fix to make sure that RxJS v7 Observable is compatible with AsyncPipe. This is a typings-only change.
For more information see: microsoft/TypeScript#43643

PR Close #41590
mhevery pushed a commit to angular/angular that referenced this issue May 4, 2021
Adds a fix to make sure that RxJS v7 Observable is compatible with AsyncPipe. This is a typings-only change.
For more information see: microsoft/TypeScript#43643

PR Close #41590
mhevery pushed a commit to angular/angular that referenced this issue May 4, 2021
Adds a fix to make sure that RxJS v7 Observable is compatible with AsyncPipe. This is a typings-only change.
For more information see: microsoft/TypeScript#43643

PR Close #41590
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants