使用 TypeScript 的 Redux Reducer 中类型上的属性不存在吗?
我正尝试在一个小的学习项目中将 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: TweetAction
为
action
允许我执行
action.payload
,并且功能正常运行...
-- 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
匹配。