To ensure that the action type for your variables is always a specific string, it's best to utilize a type alias and explicitly assign types to the variables:
export type ActionNames = 'LOAD_USERS' | 'CREATE_USER';
export const LOAD_USERS: ActionNames = 'LOAD_USERS';
export const CREATE_USER: ActionNames = 'CREATE_USER';
export interface ACTION {
type: ActionNames;
payload: any;
}
If the strings in the variables do not match any of the strings in ActionTypes
, an error will be thrown - which helps prevent mistakes. For instance, this would result in an error:
export type ActionNames = 'LOAD_USERS' | 'CREATE_USER';
export const LOAD_USERS: ActionNames = 'LOAD_USERS_TYPO'; // error, good
Update
In newer TypeScript versions, another approach is available as shown below:
const actionNames = ['LOAD_USERS', 'CREATE_USER'] as const;
type ActionNames = typeof actionNames[number]; // typed as 'LOAD_USERS' | 'CREATE_USER'
Additionally, consider defining actions with a common string literal type property distinguished by the string literal type (refer to discriminated unions).
For example:
interface LoadUsersAction {
type: "LOAD_USERS";
}
interface CreateUserAction {
type: "CREATE_USER";
name: string;
// etc...
}
type Actions = LoadUsersAction | CreateUserAction;
It is recommended to directly use strings instead of variables for better type safety.