Вывод поставщика React-Redux с Typescript? - PullRequest
0 голосов
/ 28 сентября 2019

Я учил себя некоторой машинописи и столкнулся с проблемой, которую я до конца не понимаю.Мне удалось разработать обходной путь, но он, похоже, ослабляет безопасность типов.

Минимальный пример кода проблемы:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Action, createStore, Reducer, Store } from "redux";

interface IState {
    turns: string[];
}

type TAction1 = "ACTION_1";

interface IAction1 extends Action<TAction1> {
    payload: string;
}

type TAppAction = IAction1; // Assume other action interfaes will be added via union.

// The reducer here doesn't do anything.
const reducer: Reducer<IState, TAppAction> = (state = { turns: [] }) => state;

// The Store type shown is the type returned by createStore.
// A workaround that works is to convert type to Store<IState> which appears to implicitly weaken the type of store.
const store: Store<IState, TAppAction> = createStore(reducer);

// A workaround is to use TSX here.
ReactDOM.render(
    React.createElement(Provider, { store }, // Error here
        React.createElement("div")),
    document.getElementById("root")
);

Ошибка, возвращаемая из Typescript:следующим образом:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '{ store: Store<IState, IAction1>; }' is not assignable to parameter of type 'Attributes & ProviderProps<Action<any>>'.
      Type '{ store: Store<IState, IAction1>; }' is not assignable to type 'ProviderProps<Action<any>>'.
        Types of property 'store' are incompatible.
          Type 'Store<IState, IAction1>' is not assignable to type 'Store<any, Action<any>>'.
            Types of property 'dispatch' are incompatible.
              Type 'Dispatch<IAction1>' is not assignable to type 'Dispatch<Action<any>>'.
                Type 'Action<any>' is not assignable to type 'IAction1'.ts(2769)
index copy.ts(13, 5): 'payload' is declared here.

Ясно, что перегрузка не найдена, и последние две строки меня смущают и заставляют меня спросить:

  1. Почему Action<any> выводится для Providerи впоследствии ProviderProps?Я неправильно понял, что здесь происходит?Во второй последней строке типы внезапно появляются в обратном порядке?
  2. Поскольку Provider является универсальным типом, я ожидал, что вместо этого я мог бы явно указать Provider<TAppAction>, однако выражение не может быть проанализировано.Это неправильное использование React.createElement?

Я использую следующее:

  "devDependencies": {
    "@types/react": "^16.9.3",
    "@types/react-dom": "^16.9.1",
    "@types/react-redux": "^7.1.3",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.2.0",
    "css-modules-typescript-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "source-map-loader": "^0.2.4",
    "style-loader": "^1.0.0",
    "terser-webpack-plugin": "^1.4.1",
    "ts-loader": "^6.1.2",
    "tslint": "^5.20.0",
    "typescript": "^3.6.3",
    "webpack": "^4.41.0",
    "webpack-cdn-plugin": "^3.1.4",
    "webpack-cli": "^3.3.9",
    "webpack-dev-server": "^3.8.1",
    "webpack-merge": "^4.2.2"
  },
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-redux": "^7.1.1",
    "redux": "^4.0.4"
  }

Наконец, я классифицирую себя как новичка в TS.Любые комментарии, отзывы или указатели приветствуются.

Мои ссылки:

  1. Основное руководство по Redux
  2. ReduxИспользование с Typescript Recipe
  3. Базовое руководство по React-Redux

Спасибо за чтение моего поста.

1 Ответ

0 голосов
/ 28 сентября 2019

Компилируется без ошибок:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Action, createStore, Reducer, Store } from "redux";

interface IState {
    turns: string[];
}

type TAction1 = "ACTION_1";

interface IAction1 extends Action<TAction1> {
    payload: string;
}

type TAppAction = IAction1; // Assume other action interfaes will be added via union.

// The reducer here doesn't do anything.
const reducer: Reducer<IState, TAppAction> = (state = { turns: [] }) => state;

// The Store type shown is the type returned by createStore.
// A workaround that works is to convert type to Store<IState> which appears to implicitly weaken the type of store.
const store: Store<IState, TAppAction> = createStore(reducer);

const MyApp = () =>  ( <> </>);

ReactDOM.render(
    <Provider store={store} >
      <MyApp />
    </Provider>,
   document.getElementById("react-root")

);

PS

Почему вывод <any> выводится

TSC, вероятно, говорит, что типНесоответствие, которое вызвало ошибку, все равно произошло бы, независимо от того, какой тип T использовался для определения типа Action<T>.

...