reactjs - React Redux handlingstyper ved hjelp av typeof
i det nedenfor, kodehandlingstype (action som SucceededAction) er spesifisert i reduceren og ting fungerer, men hvis jeg fjerner (som SucceededAction) får jeg en feil 'payload eksisterer ikke på typen 'SucceededAction | FailedAction'.
Nå hvis jeg erstatter konstantene med --
type_SUCCEEDED:'type_SUCCEEDED',type_FAILED:'type_FAILED' og bruk dem som type_FAILED og type_SUCCEEDED i stedet for type.FAILED, type.SUCCEEDED, det fungerer uten typekonvertering.
Så, i koden nedenfor tror jeg typeof ikke fungerer for handlingene mine, noe som gjør at jeg må typekaste i reducerne. Vil vite den eksakte årsaken til dette. Vennligst hjelp hvis du vet grunnen og hjelp meg med å finne feilen i koden nedenfor.
Takk.
//constants
export const type = {
SUCCEEDED: 'type_SUCCEEDED',
FAILED: 'type_FAILED'
};
export interface SucceededAction {
readonly type: typeof type.SUCCEEDED;
readonly payload: string;
}
export interface FailedAction {
readonly type: typeof type.FAILED;
}
//actions
export const Succeeded = (payload: string): SucceededAction => ({
type: type.SUCCEEDED,
payload,
});
export const Failed = (): FailedAction => ({
type: type.FAILED,
});
//reducer
export const myReducer = (
state: string = '',
action:
| SucceededAction
| FailedAction,
): string => {
switch (action.type) {
case type.SUCCEEDED:
return (action as SucceededAction) //type specified
.payload;
case type.FAILED:
return state;
default:
return state;
}
};Svar #1
Akkurat nå ser TypeScript både type.SUCCEEDED og type.FAILED som string. Dette betyr at handlingen din, SucceededAction | FailedAction, bare er { readonly type: string; readonly payload: string; } | { readonly type: string; }.
Typenavnene må være strengbokstaver typer for å kunne skille foreningen. Dette kan gjøres på to måter:
1) Enum-typer
Du kan gjøre din type-variabel til en enum:
export enum type {
SUCCEEDED = 'type_SUCCEEDED',
FAILED = 'type_FAILED'
};
En TypeScript-enum er både en verdi og en type, så du trenger ikke å bruke typeof lenger. Du kan bruke den som type direkte, slik:
export interface FailedAction {
readonly type: type.FAILED;
}
Dokumenter: Enum
Dette er akkurat den typen situasjon som string-enum er laget for. Etter min mening er dette den bedre tilnærmingen, men det finnes en annen løsning som er verdt å nevne.
2) som const
Du kan erklære variabelen som en bokstavelig skrivebeskyttet med as const:
export const type = {
SUCCEEDED: 'type_SUCCEEDED',
FAILED: 'type_FAILED'
} as const;
Docs: const-påstander
