If you want to ensure that the string in your variables will be the action type, then you should use a type alias and explicitly type the variables with that type:
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 don't match one of the strings in ActionTypes, then you'll get an error, which is desired to prevent mistakes. For example, this would error:
export type ActionNames = 'LOAD_USERS' | 'CREATE_USER';
export const LOAD_USERS: ActionNames = 'LOAD_USERS_TYPO'; // error, good
Update
Note that in newer versions of TypeScript the following is another option:
const actionNames = ['LOAD_USERS', 'CREATE_USER'] as const;
type ActionNames = typeof actionNames[number]; // typed as 'LOAD_USERS' | 'CREATE_USER'
Also, looking back on this question, you probably want to declare your actions with a common string literal type property that's differentiated by the string literal type (see discriminated unions).
For example:
interface LoadUsersAction {
type: "LOAD_USERS";
}
interface CreateUserAction {
type: "CREATE_USER";
name: string;
// etc...
}
type Actions = LoadUsersAction | CreateUserAction;
Also, I recommend not bothering with the variables. Using the strings directly is type safe.
Answer from David Sherret on Stack OverflowUse string literal instead of enums!
String Literal Types with variables in Typescript - Stack Overflow
Use string literal instead of enums! : typescript
How to use a string literal type as keys in an object?
Videos
If you want to ensure that the string in your variables will be the action type, then you should use a type alias and explicitly type the variables with that type:
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 don't match one of the strings in ActionTypes, then you'll get an error, which is desired to prevent mistakes. For example, this would error:
export type ActionNames = 'LOAD_USERS' | 'CREATE_USER';
export const LOAD_USERS: ActionNames = 'LOAD_USERS_TYPO'; // error, good
Update
Note that in newer versions of TypeScript the following is another option:
const actionNames = ['LOAD_USERS', 'CREATE_USER'] as const;
type ActionNames = typeof actionNames[number]; // typed as 'LOAD_USERS' | 'CREATE_USER'
Also, looking back on this question, you probably want to declare your actions with a common string literal type property that's differentiated by the string literal type (see discriminated unions).
For example:
interface LoadUsersAction {
type: "LOAD_USERS";
}
interface CreateUserAction {
type: "CREATE_USER";
name: string;
// etc...
}
type Actions = LoadUsersAction | CreateUserAction;
Also, I recommend not bothering with the variables. Using the strings directly is type safe.
You can use the typeof operator, it returns the inferred type:
export const LOAD_USERS = 'LOAD_USERS';
export const CREATE_USER = 'CREATE_USER';
export interface ACTION {
type: typeof LOAD_USERS | typeof CREATE_USER,
payload: any
}