开发者问题收集

使用 TypeScript 的 Redux Reducer 中类型上的属性不存在吗?

2020-03-17
4637

我正尝试在一个小的学习项目中将 Redux 与 TypeScript 结合使用,请按照本教程操作: https://redux.js.org/recipes/usage-with-typescript/

const INITIAL_STATE: TweetsState = {
  tweets: []
};

const tweetsReducer: Reducer<TweetsState> = (
  state = INITIAL_STATE,
  action: TweetAction
): TweetsState => {
  switch (action.type) {
    case GET_TWEETS:
      return {
        ...state
      };

    case TWEETS_RECEIVED:
      return {
        tweets: [...state.tweets, action.payload]
      };

    default:
      return state;
  }
};

我的 Reducer 需要 TweetAction 类型的操作,它是两个接口的联合:

export interface IGetTweetsAction {
  type: typeof GET_TWEETS;
}

export interface ITweetsReceivedAction {
  type: typeof TWEETS_RECEIVED;
  payload: ITweet[];
}

export const GET_TWEETS: string = "GET_TWEETS";
export const TWEETS_RECEIVED: string = "TWEETS_RECEIVED";

export type TweetAction = IGetTweetsAction | ITweetsReceivedAction;

但是,在我的 Reducer 中,我收到错误 Property 'payload' does not exist on type 'TweetAction' ,这很令人困惑,因为它表明联合没有起作用?

但这更加令人困惑,因为在我的操作文件中,它明确允许我返回一个 TweetAction 类型的对象, payload:

import {
  TweetAction,
  GET_TWEETS,
  TWEETS_RECEIVED,
  ITweet
} from "./tweets.types";

export const getTweets = (): TweetAction => ({
  type: GET_TWEETS
});

export const tweetsReceived = (tweets: ITweet[]): TweetAction => ({
  type: TWEETS_RECEIVED,
  payload: tweets
});

我知道代码目前有点乱(我有时会本能地在接口前面加上“我是 C# 开发人员”,对不起!)因为我还没有经历过重构阶段,我只是想快速完成一些事情,但是这个错误让我很困惑。

有人能看出哪里出了问题吗?这可能是一些简单的事情,但隔离可能会让我头疼。

谢谢!

编辑:请注意,删除类型安全并更改: action: TweetActionaction 允许我执行 action.payload ,并且功能正常运行...

1个回答

-- edit -----

好的,显然您需要删除这些行中的 : string 输入:

export const GET_TWEETS: string = "GET_TWEETS";
export const TWEETS_RECEIVED: string = "TWEETS_RECEIVED";

-- /edit -----

我对 typescript 也还很陌生,但据我了解,由于您在 Reducer 中使用了 action.payload ,因此 TweetAction 类型不被接受,因为它可能暗示 IGetTweetsAction 类型,而该类型未定义 payload 属性。

您需要使用更通用的类型,例如: type TweetAction { type: // ..., >

表示您可以有一个始终具有 type 的操作,并且可能具有其他一些属性(例如 payload )。

至于您令人困惑的例子,我认为这实际上使意义:

export const getTweets = (): TweetAction => ({
  type: GET_TWEETS
});

没有定义 payload ,因此它与 IGetTweetsAction 匹配。

export const tweetsReceived = (tweets: ITweet[]): TweetAction => ({
  type: TWEETS_RECEIVED,
  payload: tweets
});

而这个与 ITweetsReceivedAction 匹配。

Nicolas SEPTIER
2020-03-17