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 Overflow
🌐
MIT
web.mit.edu › 6.102 › www › sp26 › classes › 06-abstract-data-types
Reading 6: Abstract Data Types
Let’s look at a simple abstract data type to see what representation independence means and why it’s useful. The MyString type below has far fewer operations than the built-in TypeScript string, and their specs are a little different, but it’s still illustrative.
🌐
TypeScript
typescriptlang.org › docs › handbook › 2 › template-literal-types.html
TypeScript: Documentation - Template Literal Types
That literal type can be validated as being in the union of valid attributes in the generic · The type of the validated attribute can be looked up in the generic’s structure using Indexed Access · This typing information can then be applied to ensure the argument to the callback function is of the same type ... Here we made on into a generic method. When a user calls with the string "firstNameChanged", TypeScript will try to infer the right type for Key.
Discussions

Use string literal instead of enums!
The problem with string literal types is that they cannot be enumerated easily. I much prefer this instead: const usPoliticalParties = ['Democrat','Republican'] as const export type UsPoliticalParty = typeof usPoliticalParties[number]; Best of both worlds. More on reddit.com
🌐 r/typescript
107
67
July 15, 2024
String Literal Types with variables in Typescript - Stack Overflow
my codes: export const LOAD_USERS = 'LOAD_USERS'; export const CREATE_USER = 'CREATE_USER'; export interface ACTION { type: string, payload: any } I want to restrict the ACTION.type to be eith... More on stackoverflow.com
🌐 stackoverflow.com
Use string literal instead of enums! : typescript
TypeScript is a language for application-scale JavaScript development. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. More on old.reddit.com
🌐 r/typescript
How to use a string literal type as keys in an object?
Not sure why but maybe this works: type ILogStore = { [logType in LogType]: string[]; } More on reddit.com
🌐 r/typescript
3
4
April 29, 2017
🌐
Marius Schulz
mariusschulz.com › blog › more-literal-types-in-typescript
More Literal Types in TypeScript — Marius Schulz
November 22, 2020 - TypeScript 1.8 introduced string literal types for restricting variables to a finite set of possible string values. With TypeScript 2.0, literal types are no longer restricted to string literals.
🌐
Reddit
reddit.com › r/typescript › use string literal instead of enums!
r/typescript on Reddit: Use string literal instead of enums!
July 15, 2024 - We’re using TypeScript just for type checking, so let’s do it in a way that doesn’t add any extra ... Enums don't add runtime overhead if used as types with the type checker. They only add runtime overhead when used at runtime. Which is something you can't do with string literals, so this is a win for enums.
🌐
Microsoft Developer Blogs
devblogs.microsoft.com › dev blogs › typescript › announcing typescript 6.0 beta
Announcing TypeScript 6.0 Beta - TypeScript
February 11, 2026 - These methods have been added to the esnext lib so that you can start using them immediately in TypeScript 6.0. With getOrInsert, we can replace our code above with the following: function processOptions(compilerOptions: Map<string, unknown>) { let strictValue = compilerOptions.getOrInsert("strict", true); // ...
🌐
typescriptlang.org
typescriptlang.org › docs › handbook › 2 › everyday-types.html
TypeScript: Documentation - Everyday Types
In addition to the general types ... specific strings and numbers in type positions. One way to think about this is to consider how JavaScript comes with different ways to declare a variable. Both var and let allow for changing what is held inside the variable, and const does not. This is reflected in how TypeScript creates types for literals...
Find elsewhere
🌐
DZone
dzone.com › coding › javascript › how template literal types work in typescript
How Template Literal Types Work in TypeScript
June 20, 2022 - That means that the first part of type ID needs to conform to type startOfId, while the second bit can be a string or number. The entire type ID must be a string since a template literal implies a string type.
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › what-are-string-literal-types-in-tpescript
What are string literal types in TypeScript ? - GeeksforGeeks
July 23, 2025 - These properties can be combined to give strings enum-like functionality. The string literal type allows you to specify a set of possible string values for a variable, only those string values can be assigned to a variable.
🌐
Total TypeScript
totaltypescript.com › workshops › type-transformations › template-literals › only-allow-specified-string-patterns › solution
Template Literal with Strings | Total TypeScript
June 8, 2023 - 0:00 The way to do this is by using a template literal bit of syntax here. We're using this little backtick here to indicate that this is a string of a certain value.
Top answer
1 of 5
23

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.

2 of 5
16

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
}
🌐
DEV Community
dev.to › dance2die › dynamically-build-typescript-string-literal-type-1bc7
Dynamically build TypeScript string literal type - DEV Community
February 2, 2019 - TypeScript has String Literal Types, which lets you specify what string value is allowed for a variable.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Template_literals
Template literals (Template strings) - JavaScript | MDN
Template literals are enclosed by backtick (`) characters instead of double or single quotes. Along with having normal strings, template literals can also contain other parts called placeholders, which are embedded expressions delimited by a dollar sign and curly braces: ${expression}. The strings and placeholders get passed to a function — either a default function, or a function you supply.
🌐
Angular
angular.dev › guide › components › inputs
Accepting data with input properties • Angular
However, Angular's booleanAttribute treats the literal string "false" as the boolean false. numberAttribute attempts to parse the given value to a number, producing NaN if parsing fails. You can specify the alias option to change the name of an input in templates. @Component({ /*...*/})export class CustomSlider { value = input(0, {alias: 'sliderValue'});} <custom-slider [sliderValue]="50" /> This alias does not affect usage of the property in TypeScript code.
🌐
Total TypeScript
totaltypescript.com › tips › understand-how-typescript-infers-literal-types
Understand how TypeScript infers literal types | Total TypeScript
So, age instead of just being inferred as a number, it's actually inferred as its literal type as 31 which is really interesting. ... I can sort of force this on the let by saying age is 31 and then it gets inferred. And then, if I try to reassign to it, it's not going to let me because 31 is not assignable to type 32. ... The same is true for strings too so the constant name "Matt" is actually being inferred as "Matt", but it gets more complicated when you go to arrays and objects.
Published   May 30, 2023
🌐
TutorialsPoint
tutorialspoint.com › typescript › typescript_template_literal_types.htm
TypeScript - Template Literal Types
In this code, the 'size' type contains the union of multiple type values. The 'ResponseMessage' type is a template literal type whose value changes based on the value of the 'Size' type. The selectSize() function takes a string of type 'Size' as a parameter, and returns the value of type 'ResponseMessage'.
🌐
Medium
medium.com › @frontendhub › understanding-typescript-template-literal-types-a-deep-dive-920db9e1fbdd
Understanding TypeScript Template Literal Types: A Deep Dive | by Frontend Hub | Medium
January 10, 2025 - Template literal types, introduced in TypeScript 4.1, represent one of the most powerful features for type-level string manipulation. They…
🌐
Mozilla
developer.mozilla.org › en-US › docs › Web › JavaScript › Guide › Grammar_and_types
Grammar and types - JavaScript | MDN
You can call any of the String object's methods on a string literal value. JavaScript automatically converts the string literal to a temporary String object, calls the method, then discards the temporary String object.
🌐
TypeScript Tutorial
typescripttutorial.net › home › typescript tutorial › typescript string literal types
TypeScript String Literal Types
July 11, 2024 - A TypeScript string literal type defines a type that accepts specified string literal.
🌐
Alex MacArthur
macarthur.me › posts › template-literal-types
I didn't know you could compose template literal types in TypeScript. | Alex MacArthur
January 20, 2025 - But as you might expect, it can be composed of other TypeScript features too, like its built-in utility types (would've been really nice using this earlier on building PicPerf). type ImageExtension = `png` | `jp${`e` | ``}g` | `webp`; type ImageFileName = `${Lowercase<string>}.${ImageExtension}`; const goodName1: ImageFileName = 'doggy1.jpeg'; const goodName2: ImageFileName = 'doggy2.jpg'; const badName: ImageFileName = 'KittyCat.webp';