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

Unsafe overload resolution issue #21135

Closed
JasonKleban opened this issue Jan 11, 2018 · 3 comments
Closed

Unsafe overload resolution issue #21135

JasonKleban opened this issue Jan 11, 2018 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@JasonKleban
Copy link

v2.6.2

Overload resolution makes an unsafe assumption when the type of the parameter is unknowable:

interface ParsedResponseBody { a: string }
interface RawResponse { b : string }

let obj: {
    get(): Promise<ParsedResponseBody>
    get(rawResponse: false): Promise<ParsedResponseBody>
    get(rawResponse: true): Promise<RawResponse>
} = <any>{};

obj.get().then(x => x) // x : ParsedResponseBody - CORRECT
obj.get(false).then(x => x) // x : ParsedResponseBody - CORRECT
obj.get(true).then(x => x) // x : RawResponse - CORRECT

// x : ParsedResponseBody - INCORRECT, should be `RawResponse  | ParsedResponseBody` or `any`
obj.get(<any>null).then(x => x) 
@DanielRosenwasser DanielRosenwasser added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jan 11, 2018
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jan 11, 2018

any is assignable to anything, so I don't really know what you could expect otherwise. We do have special a pre-pass for overload resolution where we try to resolve using subtyping instead of assignability, so you could add an overload to "catch" the any behavior first

declare let obj: {
    get(): Promise<ParsedResponseBody>
    get(rawResponse: false): Promise<ParsedResponseBody>
    get(rawResponse: true): Promise<RawResponse>

    // Should throw at runtime, can never return.
    get(rawResponse: any): never
};

But really, I think you should avoid relying on this behavior. The real solution is to avoid using any when you can.

@JasonKleban
Copy link
Author

Hmm, I was trying to illustrate this situation, but I went too broad:

function ex(raw : boolean) {
    // type error - "Argument of type 'boolean' is not assignable to parameter of type 'true'."
    obj.get(raw).then(x => x) 
}

not any but a boolean that we don't know is either true or false. This being an error is an improvement over the unsafe assumption I thought at first. But couldn't the checker do better here?

@DanielRosenwasser
Copy link
Member

So something like #14107

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
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