I have a typescript react/ redux component which won't compile. I have other components that are almost exactly the same and do compile. I need to understand why this one is not compiling.
Non-compiling component source (in full):
import * as React from 'react';
import { connect } from 'react-redux';
import { ApplicationState } from '../store';
interface ToastProps {
messages: string[]
}
interface FadeState {
visible: boolean
}
class ToastBar extends React.Component<ToastProps, FadeState> {
public render() {
if (this.props.messages.length > 0) {
this.state = { visible: true };
} else {
this.state = { visible: false };
}
let key = 0;
return <div id="toastbar" className={this.state.visible ? 'show' : ''}>
{this.props.messages.map(function (listValue) {
return <p key={++key}>{listValue}</p>;
})}
</div>;
}
}
const mapStateToProps = (state: ApplicationState, ownProps?: ToastProps) => ({
messages: state ? state.toastMessages.messages : []
});
export default connect(mapStateToProps, {}, null, { pure: false })(ToastBar);
I get this error message from the IDE and from running an npm run-script build:
(9,82): Argument of type 'typeof ToastBar' is not assignable to parameter of type 'ComponentType>'. Type 'typeof ToastBar' is not assignable to type 'StatelessComponent>'. Type 'typeof ToastBar' provides no match for the signature '(props: Shared<{ messages: String[]; }, ToastProps> & { children?: ReactNode; }, context?: any): ReactElement | null'.
Here is another component which compiles fine:
import * as UserStore from '../store/UserManagement';
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { ApplicationState } from '../store';
import { connect } from 'react-redux';
import { User, UserRole } from '../model/User';
import { UserEditDialog } from './UserEditDialog';
interface UserMgmtState {
isLoading: boolean;
users: User[];
currentUser: User;
}
interface UserEditState {
editingUser: User | null;
}
type DispatchProps = typeof UserStore.actionCreators;
type UserManagementProps = UserMgmtState & DispatchProps & RouteComponentProps<{}>;
class UserManagement extends React.Component<UserManagementProps, UserEditState> {
componentWillMount() {
// snipped
}
editUser(user: User) {
this.setState({
editingUser: user
});
}
stopEditingUser() {
this.setState({
editingUser: null
});
}
deleteUser(user: User) {
if (confirm('Delete ' + user.fullName + '. Are you sure?'))
this.props.deleteUser(user.name);
}
userIsCurrentUser(user: User): boolean {
return this.props.currentUser.name == user.name;
}
saveUserEdit(user: User) {
this.props.updateUser(user);
this.setState({
editingUser: null
});
}
displayRoles(roles: UserRole[]): string {
return roles.join(', ');
}
renderUsersTable(): any {
if (this.props.isLoading) {
return <div>Loading users</div>;
}
else {
return <div>
<!-- snipped -->
</div>;
}
}
public render() {
return <div>
<h1>User Management</h1>
{this.renderUsersTable()}
</div>;
}
}
const mapStateToProps = (state: ApplicationState, ownProps?: UserMgmtState) => ({
isLoading: state ? state.userManagement.isLoading : false,
users: state ? state.userManagement.users : [],
currentUser: state ? state.loggedInUser.currentUser : null
});
export default connect(
mapStateToProps, // Selects which state properties are merged into the component's props
UserStore.actionCreators // Selects which action creators are merged into the component's props
)(UserManagement);
Why does UserManagement compile, and Toastbar not? I am really mystified here...