I'm trying to combine switch case String
into an object, but somehow typescript is mis-interpreting the switch case in useReducer
:
Before version, this works fine:
export const LOGIN_USER = "LOGIN_USER";
export const LOGOUT_USER = "LOGOUT_USER";
export type AuthActionType = LogInUser | LogOutUser;
type LogInUser = { type: typeof LOGIN_USER; payload: User }; // <- notice this
type LogOutUser = { type: typeof LOGOUT_USER };
export default function authReducer(
state: AuthStateType,
action: AuthActionType
) {
switch (action.type) {
case LOGIN_USER: {
return {
...state,
user: {
username: action.payload.username, // <- correctly inferring action.payload.username
password: action.payload.password
}
};
}
case LOGOUT_USER: {
return {
...state,
user: null
};
}
default: {
return state;
}
}
}
However this breaks, after putting the switch case
into an object:
export const AUTH = {
LOGIN_USER: "LOGIN_USER",
LOGOUT_USER: "LOGOUT_USER"
};
export type AuthActionType = LogInUser | LogOutUser;
type LogInUser = { type: typeof AUTH.LOGIN_USER; payload: User }; // <- notice this
type LogOutUser = { type: typeof AUTH.LOGOUT_USER };
export default function authReducer(
state: AuthStateType,
action: AuthActionType
) {
switch (action.type) {
case LOGIN_USER: {
return {
...state,
user: {
username: action.payload.username, // <- error over here, cannot infer the correct case?
password: action.payload.password
}
};
}
case LOGOUT_USER: {
return {
...state,
user: null
};
}
default: {
return state;
}
}
}
Only by changing the type definition from type: typeof LOGIN_USER
to type: typeof AUTH.LOGIN_USER
, typescript breaks the switch case, how's this happenning?
Sandbox, please take a look at this minimum reproduced version.
CodePudding user response:
You can use const assertions to let typescript not convert ('LOGIN_USER' to string)
export const AUTH = {
LOGIN_USER: "LOGIN_USER",
LOGOUT_USER: "LOGOUT_USER"
} as const;
CodePudding user response:
Change AUTH to an enum
export enum Auth { LOGIN_USER = “LOGIN_USER” …code }
CodePudding user response:
In the second example you changed the constant values at the top to be an Object of strings where in the first example they are just string constants. I would update the case statements in your second example to match the object:
case AUTH.LOGIN_USER:
...
case AUTH.LOGOUT_USER:
...