【问题标题】:Property does not exist on type within Redux reducer using TypeScript?使用 TypeScript 的 Redux reducer 中的类型不存在属性?
【发布时间】:2020-06-28 15:42:04
【问题描述】:

我正在尝试在一个小型学习项目中将 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;

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

但这更加令人困惑,因为在我的操作文件中,它清楚地允许我返回一个 TweetAction 类型的对象,并带有有效负载:

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: TweetAction 到 action 允许我做 action.payload 并且功能工作正常......

【问题讨论】:

    标签: reactjs typescript redux


    【解决方案1】:

    --编辑-----

    好吧,显然你需要删除: string在这些行中输入:

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

    -- /编辑 -----

    我对打字稿也很陌生,但据我了解,由于您在减速器中使用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。

    【讨论】:

    • 虽然我明白你在说什么,但可以在此处找到示例:redux.js.org/recipes/usage-with-typescript 显示了一个场景,其中 ChatActionTypes 可以包含有效负载或元时间戳,并且使用工会运营商,就像我试图做的那样。这可能是 TypeScript 之间的某些概念不同的地方,以及接口如何在其他语言中运行?
    • 我发现它适用于 redux 文档,因为它们没有在常量 SEND_MESSAGE 上指定 : string。基本上这是可行的:export const SEND_MESSAGE = 'SEND_MESSAGE',但这不是export const SEND_MESSAGE: string = 'SEND_MESSAGE' 不知道为什么,虽然:/
    • 你可以在这里测试:codesandbox.io/s/boring-blackburn-hv1pv
    • 你已经破解了,是琴弦!是的,我不知道为什么这也会有所作为。但重要的是它现在有效。感谢 Nicolas 的帮助 :) 如果您想通过底部的编辑来编辑您的初始答案,其中包含更改字符串的提示,很高兴将其选为对您的业力有帮助的正确答案!
    • 我已经编辑了我的帖子。我真的很想解释为什么用 typeof [SOME_CONSTANT] 定义类型而不是输入这些常量,而不是 type: string 工作......
    猜你喜欢
    • 2022-07-31
    • 1970-01-01
    • 2023-01-19
    • 2019-02-13
    • 2017-07-28
    • 2019-04-09
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多