reactjs - Egenskap finns inte på typ inom Redux-reducer som använder TypeScript?
Jag försöker använda Redux med TypeScript i ett litet lärandeprojekt, och följer denna handledning: 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;
}
};
Min reducer förväntar sig en åtgärd av typen TweetAction, som är unionen av två gränssnitt:
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;
Men inom min reducer får jag felet Property 'payload' does not exist on type 'TweetAction' vilket är förvirrande eftersom det antyder att unionen inte har fungerat?
Men detta är ytterligare förvirrande eftersom det inom min actions-fil tydligt tillåter mig att returnera ett objekt, av typen TweetAction, med en 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
});
Jag är medveten om att koden för närvarande är lite rörig (jag prefixar ibland instinktivt gränssnitt med I eftersom jag är en C#-utvecklare, förlåt!) eftersom jag inte har gått igenom en refaktoreringsfas än då jag bara försöker slänga ihop något snabbt, men jag har blivit förbryllad av detta fel.
Kan någon se vad som går fel? Det är förmodligen något enkelt, men isoleringen kanske börjar påverka mitt huvud.
Tack!
Redigera: Observera att genom att ta bort typ-säkerheten och ändra: action: TweetAction till bara action tillåts jag att göra action.payload och funktionaliteten fungerar bra...
Svar #1
-- redigera -----
Okej, så tydligen behöver du ta bort : string-typningen i de raderna:
export const GET_TWEETS: string = "GET_TWEETS";
export const TWEETS_RECEIVED: string = "TWEETS_RECEIVED";
-- /redigera -----
Jag är ganska ny på TypeScript också, men som jag förstår det, eftersom du använder action.payload i din reducer, accepteras inte typen TweetAction eftersom det kan innebära en IGetTweetsAction-typ, som inte definierar en payload-egenskap.
Du behöver använda en mer generisk typ som: type TweetAction { type:/..., }
att säga att du kan ha en åtgärd som alltid kommer att ha en type och kan ha några andra egenskaper (som ett payload).
När det gäller ditt förvirrande exempel tror jag faktiskt att det är meningsfullt:
export const getTweets = (): TweetAction => ({
type: GET_TWEETS
});
Ingen payload är definierad så den matchar IGetTweetsAction.
export const tweetsReceived = (tweets: ITweet[]): TweetAction => ({
type: TWEETS_RECEIVED,
payload: tweets
});
Medan denna matchar ITweetsReceivedAction.
