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

Type inference cannot properly infer type for object literal returned from function #20008

Closed
aczekajski opened this issue Nov 14, 2017 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@aczekajski
Copy link

TypeScript Version: 2.6.0 and 2.7.0-dev.20171114

Code

declare namespace Module {
    class MyClass<T> {
        // template functions using Pick 
        foo<K extends keyof T>(o: Pick<T, K>): void;
        foo<K extends keyof T>(f: () => Pick<T, K>): void;

        // simple example without generics and Pick 
        bar(o: T): void;
        bar(f: () => T): void;  
    }
}

interface I {
    value: number;
}

class C extends Module.MyClass<I> {
    private fn() {
        this.foo({ nothing: 5 }); // ERROR | here it knows that "nothing" does not exist on I
        this.foo(() => ({ nothing: 5 })); // NO ERROR | but now it cannot infer that "nothing" does not exist on I
        this.foo<keyof I>(() => ({ nothing: 5 })); // ERROR | we explicitely provided a "keyof I" so K from line 6 is no longer inferred, and now it is able to say that the "value" property is missing, good 
        this.foo<keyof I>(() => ({ nothing: 5, value: 6 })); // NO ERROR | then we add missing "value" property to returned object and it still cannot see the additional "nothing", even though it was able to infer some information about the object

        // the same goes for the "bar" function, so it is not a problem of generics 
        this.bar({ nothing: 5 }); // ERROR | as desired
        this.bar(() => ({ nothing: 5 })); // ERROR | can see missing "value"
        this.bar(() => ({ nothing: 5, value: 6 })); // NO ERROR | cannot see unwanted "nothing"
    }
}

See the code in TypeScript playground.

Expected behavior:
Errors in all lines invoking foo and bar functions, saying that property nothing does not exist on type I or Pick<I, /* something */>.

Actual behavior:
TypeScript properly raises an error when foo/bar function gets an object literal that is incompatible with type I; It properly raises an error about property missing in object literal returned from function being passed to foo/bar when we explicitely specify which type we want to be returned, but cannot raise an error about nothing being incompatible with I when it's being returned from function (even with <keyof I> being explicitely specified for foo).

@aczekajski aczekajski changed the title Type inference for returned parameters cannot properly infer type returned from function Type inference cannot properly infer type for object literal returned from function Nov 14, 2017
@RyanCavanaugh
Copy link
Member

Duplicate #241 - the widening of the types of the function expressions' return values is what's causing this

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Nov 14, 2017
@RyanCavanaugh
Copy link
Member

See also #7547

@typescript-bot
Copy link
Collaborator

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

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants