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

Unable to infer types correctly from generic on function #26418

Closed
agubler opened this issue Aug 13, 2018 · 3 comments
Closed

Unable to infer types correctly from generic on function #26418

agubler opened this issue Aug 13, 2018 · 3 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@agubler
Copy link

agubler commented Aug 13, 2018

TypeScript Version: 3.0.1-insiders.20180726 (typescript playground version)

Search Terms:

generic, inference

Code

Note: noImplicitAny set to true

class BaseClass<P = any> {
    public props: P;
}

function w<W extends BaseClass>(
    ctr: (new () => W),
    props: W['props']
) { }

interface MyClassProps {
    myFunc(options: { foo: string }): void;
}

class MyClass extends BaseClass<MyClassProps> {}

// eplicit passing the generic
w<MyClass>(MyClass, {
    myFunc(options) {
        options.foo; // correctly infers prop
        options.bar; // correctly errors
    }
});

// inferring `myFunc` sig types based on `MyClass` argument
w(MyClass, {
    myFunc(options) { // doesn't infer argument type
        options.foo;
        options.bar;
    }
 });

Expected behavior:

Expected the argument of the function to be inferred correctly.

Actual behavior:

Doesn't infer the argument type or provide auto complete on the props of the w() function (does however type check)

Playground Link: http://www.typescriptlang.org/play/#src=class%20BaseClass%3CP%20%3D%20any%3E%20%7B%0A%20%20%20%20public%20props%3A%20P%3B%0A%7D%0A%0Afunction%20w%3CW%20extends%20BaseClass%3E(%0A%20%20%20%20ctr%3A%20(new%20()%20%3D%3E%20W)%2C%0A%20%20%20%20props%3A%20W%5B'props'%5D%0A)%20%7B%20%7D%0A%0Ainterface%20MyClassProps%20%7B%0A%20%20%20%20myFunc(options%3A%20%7B%20foo%3A%20string%20%7D)%3A%20void%3B%0A%7D%0A%0Aclass%20MyClass%20extends%20BaseClass%3CMyClassProps%3E%20%7B%7D%0A%0A%2F%2F%20eplicit%20passing%20the%20generic%0Aw%3CMyClass%3E(MyClass%2C%20%7B%0A%20%20%20%20myFunc(options)%20%7B%0A%20%20%20%20%20%20%20%20options.foo%3B%20%2F%2F%20correctly%20infers%20prop%0A%20%20%20%20%20%20%20%20options.bar%3B%20%2F%2F%20correctly%20errors%0A%20%20%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20inferring%20%60myFunc%60%20sig%20types%20based%20on%20%60MyClass%60%20argument%0Aw(MyClass%2C%20%7B%0A%20%20%20%20myFunc(options)%20%7B%20%2F%2F%20doesn't%20infer%20argument%20type%0A%20%20%20%20%20%20%20%20options.foo%3B%0A%20%20%20%20%20%20%20%20options.bar%3B%0A%20%20%20%20%7D%0A%20%7D)%3B

Related Issues: Possibly related to #14829?

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Aug 13, 2018
@RyanCavanaugh
Copy link
Member

Generic inference is a single-pass process; inferring a type for options here would require a process of an arbitrary number of passes.

#14829 wouldn't fix this on its own, but it'd be a prerequisite for deferring applying a type to the options parameter to allow a contextual type from T to be present.

@agubler
Copy link
Author

agubler commented Aug 13, 2018

Thanks for the response @RyanCavanaugh, glad that I’m not just doing something silly!

@agubler
Copy link
Author

agubler commented Feb 20, 2019

@RyanCavanaugh Interestingly using tsx with the following a simple global JSX namespace

declare global {
	namespace JSX {
		type Element = any;
		interface ElementAttributesProperty {
			props: {};
		}
	}
}

the properties and any function arguments are all inferred correctly:

<MyClass myFunc={(options) { 
    options.foo; // correctly infers prop
    options.bar; // correctly errors
}}/>

I guess this is because something "special" is happening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

2 participants