I'm going to use Discriminated Union type for Reducer Action.
But when I use it the compiler says the payload does not contain the property.
The code looks like
interface AuthenticatedUserState {
user?: any
isAdmin?: boolean
isRegistered?: boolean
err?: any
isError?: boolean
isSignedOut?: boolean
authorizationData?: any
}
const INITIAL_STATE: AuthenticatedUserState = {
user: null,
isError: false,
err: null,
isSignedOut: false
}
interface AUTHENTICATED_USER_ACTION {
type: 'authentication/AUTHENTICATED_USER'
payload: {
authenticatedUser: any
isAdmin: boolean
}
}
interface REGISTER_USER_ACTION {
type: 'authentication/REGISTER_USER'
payload: {
isRegistered: boolean
err: any
}
}
const AUTHENTICATED_USER = 'authentication/AUTHENTICATED_USER'
const REGISTER_USER = 'authentication/REGISTER_USER'
type ACTION = AUTHENTICATED_USER_ACTION | REGISTER_USER_ACTION
const authenticatedUserReducer = (
state: AuthenticatedUserState = INITIAL_STATE,
action: ACTION
): AuthenticatedUserState => {
const { type, payload } = action
switch (type) {
case AUTHENTICATED_USER:
return {
...state,
user: payload.authenticatedUser,
isAdmin: payload.isAdmin
}
case REGISTER_USER:
return {
...state,
isRegistered: payload.isRegistered,
err: payload.err
}
default:
return state
}
}
Then, the error is
Property 'err' does not exist on type '{ authenticatedUser: any; isAdmin: boolean; } | { isRegistered: boolean; err: any; }'.
Property 'err' does not exist on type '{ authenticatedUser: any; isAdmin: boolean; }'.
You can fix the error by upgrading your TypeScript version. See playground with v4.9.4: Playground
It appears that you might be using a typescript version < 4.6.
With TS < 4.6, when you destructure a value with a discriminated-union type:
const { type, payload } = action
you are creating two new variables that have no connection with each other, nor the item from which they were destructured. The compiler is unable to narrow payload
or action
by means of checking type
.
This behaviour changes in typescript > 4.6 , so upgrading your typescript version should be considered.
Otherwise, in a pre-TS4.6 world, don't destructure items from your discriminated union for the purpose of type-narrowing/control-flow.
switch (action.type) {
case AUTHENTICATED_USER:
return {
...state,
user: action.payload.authenticatedUser,
isAdmin: action.payload.isAdmin
}
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.