Ошибка компиляции Typescript Redux при подключении (компонент не соответствует сигнатуре) - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть компонент реакции / редукции машинописи, который не будет компилироваться У меня есть другие компоненты, которые почти одинаковы и компилируются. Мне нужно понять, почему этот не компилируется.

Источник некомпилируемого компонента (полностью):

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);

Я получаю это сообщение об ошибке из IDE и при запуске сборки сценария запуска npm:

(9,82): Аргумент типа 'typeof ToastBar' не может быть назначен параметр типа 'ComponentType>'. Тип typeof ToastBar нельзя назначить типу 'StatelessComponent>'. Тип 'typeof ToastBar' не обеспечивает совпадения для подписи '(props: Shared <{messages: String [];}, ToastProps> & {children ?: ReactNode; }, контекст ?: любой): ReactElement | нуль».

Вот еще один компонент, который прекрасно компилируется:

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);

Почему UserManagement компилируется, а Toastbar нет? Я действительно озадачен здесь ...

1 Ответ

0 голосов
/ 13 сентября 2018

Проблема заключалась в том, что свойство state.toastMessages.messages имело тип String [], а свойство ToastProps.messages имело строку типа []

Это разные типы, поэтому TypeScript не учитывалрезультат использования метода mapStateToProps того же типа, что и интерфейс ToastProps.

В случае, если у кого-то еще есть подобная проблема и он хочет знать, как ее устранить: Чтобы выяснить это, я изменил однострочный метод mapStateToPropsк многострочному методу, определяющему и возвращающему результат, тогда проблема компиляции обнаружилась там.Когда я узнал, что выходные данные mapStateToProps имеют несовместимый тип, я проверил тип state.toastMessages.messages и обнаружил проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...