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

Decorated type checked differently based on where they are used #19407

Closed
pdeva opened this issue Oct 22, 2017 · 3 comments
Closed

Decorated type checked differently based on where they are used #19407

pdeva opened this issue Oct 22, 2017 · 3 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@pdeva
Copy link

pdeva commented Oct 22, 2017

This is related to react-redux types give errors when used as decorators

TypeScript Version: 2.5.3

Code

import * as React from "react";
import {connect} from "react-redux";

interface IStore {
	myVar: any;
}

interface MyComponentProps {
	dispatch?: any;
	a;
}

function mapStateToProps(state: IStore) {
	return {
		a: state.myVar
	};
}

@connect(mapStateToProps)
export class MyComponent extends React.Component<any, any>
{
	constructor(props, context)
	{
		super(props, context);
	}

	render()
	{
		return (<div>
			<h2>Hello</h2>
		</div>);
	}
}

Expected behavior:
Should compile properly

Actual behavior:

Results in error:

MyComponent.tsx(19,1): error TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type 'ComponentClass<Pick<any, never>> & { WrappedComponent: ComponentType<any>; }' is not assignable to type 'typeof MyComponent'.
    Type 'Component<Pick<any, never>, ComponentState>' is not assignable to type 'MyComponent'.
      Types of property 'render' are incompatible.
        Type '() => false | Element' is not assignable to type '() => Element'.
          Type 'false | Element' is not assignable to type 'Element'.
            Type 'false' is not assignable to type 'Element'.

However, when used like this, TypeScript compiles it fine:

export const x = connect(mapStateToProps)(MyComponent);

Why is type-checking different in both cases, when it should be the same?

@pelotom
Copy link

pelotom commented Oct 23, 2017

See #4881. TypeScript decorators are severely limited at the moment; a function can't be used as a decorator if it changes the type of the thing it's decorating.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 23, 2017

A decorator can change the type as long as it is assignable to the original declaration.
In this case render return type is inferred to be Element and not false | Element. The root cause of this issue really is #1373. The usual expectation is that render will inherit the return type of its base class, and not override it, but that is not the case(#1373 has more details).

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Oct 23, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Nov 7, 2017

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

@mhegazy mhegazy closed this as completed Nov 7, 2017
@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
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants