Typescript + Recompose - ошибка типа в жизненном цикле

Недавно я начал комбинировать React с TypeScript. У меня проблема с использованием метода жизненного цикла Recompose. В componentDidMount я получил ошибку «Свойство« приращение »не существует для типа« {} »». Я знаю, что это проблема типа, но у меня нет большого опыта работы с TS. Куда добавить типы, чтобы исправить это? Вот мой код:

import React, { ComponentType } from 'react';
import { createStore, combineReducers, Store, Action, Reducer } from 'redux';
import { connect } from "react-redux";
import { compose, lifecycle } from 'recompose';

//TYPES
const types = {
    INCREMENT: 1,
    DECREMENT: 2
};

//ACTION CREATORS
interface InumberAction extends Action {
    payload: number;
};

const increment = (num: number): InumberAction => ({
    type: types.INCREMENT,
    payload: num
});

const decrement = (num: number): InumberAction => ({
    type: types.INCREMENT,
    payload: num
});

interface IState {
    value: number;
};

interface IStore {
    state: IState
};

const initialState = {
    state: {
        value: 0
    }
};

//REDUCERS
const stateReducer: Reducer<IState> = (state = { value: 0 }, action) => {
    switch (action.payload) {
        case types.INCREMENT: return { value: state.value + action.payload };
        case types.DECREMENT: return { value: state.value - action.payload };
        default: return state;
    }
};

const rootReducer = combineReducers({
    state: stateReducer
});

//STORE
const store: Store<IStore> = createStore(rootReducer, initialState);

//COMPONENT
interface IProps {
    value: number;
    increment: () => void;
    decrement: () => void;
}

export const Component: ComponentType<any> = ({ value }) => {
    return <h1>{value}</h1>;
};

const enhance = compose(lifecycle({
    componentDidMount() {
        this.props.increment(2);
    }
}),
    connect((state: IStore) => ({
        number: state.state.value
    }), dispatch => ({
        increment: (num: number) => dispatch(increment(num)),
        decrement: (num: number) => dispatch(decrement(num))
    }))
);

export const App = enhance(Component);

РЕДАКТИРОВАТЬ: после предложенного изменения я получил это:

Argument of type 'StatelessComponent<IProps>' is not 
assignable to parameter of type 'ComponentType<{}>'.
  Type 'StatelessComponent<IProps>' is not assignable to 
type 'StatelessComponent<{}>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type '{ children?: ReactNode; }' is not assignable to type 'IProps & { children?: ReactNode; }'.
        Type '{ children?: ReactNode; }' is not assignable to type 'IProps'.
          Property 'value' is missing in type '{ children?: ReactNode; }'.

Я использую следующие зависимости:

  "devDependencies": {
    "@types/webpack-env": "^1.13.6",
    "awesome-typescript-loader": "^5.2.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "html-webpack-plugin": "^3.2.0",
    "react-hot-loader": "^4.3.3",
    "source-map-loader": "^0.2.3",
    "typescript": "^2.9.2",
    "webpack": "^4.12.1",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.1.4"
  },
  "dependencies": {
    "@types/react": "^16.4.1",
    "@types/react-dom": "^16.0.6",
    "@types/react-redux": "^6.0.2",
    "@types/react-router-dom": "^4.2.7",
    "@types/recompose": "^0.26.1",
    "@types/rx": "^4.1.1",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
    "recompose": "^0.27.1",
    "redux": "^4.0.0",
    "rxjs": "^6.2.1"
  }

person E1-XP    schedule 30.06.2018    source источник


Ответы (1)


Пытаться:

const enhance = compose(lifecycle<IProps, {}>({
    componentDidMount() {
        this.props.increment(2);
    }
}),

Первый параметр типа для lifecycle — это интерфейс реквизита, второй — интерфейс состояния (который вы здесь не используете, но, к сожалению, определения типов библиотеки не дают {} по умолчанию, хотя, вероятно, должны).

Совет: используйте код VS и используйте Перейти к определению для lifecycle, чтобы увидеть его объявление:

export function lifecycle<TProps, TState, TInstance = {}>(
    spec: ReactLifeCycleFunctions<TProps, TState, TInstance> & TInstance
): InferableComponentEnhancer<{}>;

(Обратите внимание, что вам не нужно ставить интерфейсы с префиксом I, и это не рекомендуется в стиле TS.)

Затем вы увидите фактическую ошибку типа, заключающуюся в том, что вы передаете 2 в качестве аргумента increment, даже если он не принимает никаких параметров.

person Daniel Earwicker    schedule 30.06.2018
comment
Я обновил интерфейс IProps, чтобы он принимал числовой аргумент в функциях увеличения/уменьшения. Я пробовал ваше решение раньше, но оно дает мне еще одно предупреждение (добавлено в пост); - person E1-XP; 30.06.2018
comment
@ E1-XP Возможно, вам стоит попробовать обновить пакеты. Я только что установил все пакеты, которые вы импортируете, и он без проблем скомпилировал ваш (исправленный) код. - person Daniel Earwicker; 30.06.2018
comment
npm install говорит, что все обновлено. Добавил свои зависимости в первый пост. - person E1-XP; 30.06.2018
comment
Я забыл добавить, что эта красная предупреждающая строка находится под компонентом в последней строке. - person E1-XP; 30.06.2018
comment
Хорошо, я отключил строгий режим в своем файле tsconfig. Так это работает. - person E1-XP; 30.06.2018
comment
@E1-XP странно, мой тест был со strict: true - person Daniel Earwicker; 30.06.2018