String Literal Types with variables in Typescript
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
}
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.