Question
How to Check if a Value Exists in an Enum-Like Object in TypeScript
Question
I receive a numeric value such as 3 and need to check whether it exists in this TypeScript constant object:
export const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
};
One approach I found is to convert the object values into an array and then use indexOf, for example:
if (-1 < _.values(MESSAGE_TYPE).indexOf(_.toInteger(type))) {
// do stuff...
}
Is there a simpler and more readable way to check whether a value exists in this enum-like object?
Short Answer
By the end of this page, you will understand how to check whether a value exists inside an enum-like object in TypeScript. You will learn readable approaches using Object.values(), how this differs from checking keys, when to use a real enum, and how to avoid common mistakes with string and number comparisons.
Concept
In this question, the main concept is checking whether a value exists in a fixed set of allowed constants.
Your MESSAGE_TYPE example looks like an enum, but technically it is a plain object used as an enum-like constant map:
export const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
};
This is common in TypeScript and JavaScript projects. Developers often use objects like this to define a small set of valid values.
The goal is simple:
- you receive some input such as
3 - you want to know whether that number is one of the allowed values
A readable way to do this is:
Object.values(MESSAGE_TYPE).includes(type)
If type might not already be a number, convert it first:
Object.values().(())
Mental Model
Think of MESSAGE_TYPE like a small menu:
INFO→ 1SUCCESS→ 2WARNING→ 3ERROR→ 4
If someone gives you the number 3, you are not asking:
- “Is there a menu item named
3?”
You are asking:
- “Is
3one of the codes on the menu?”
So the job is to scan the list of allowed codes and see whether the number appears there.
A simple mental model:
- keys are the labels on the boxes
- values are the contents inside the boxes
Your question is about checking the contents, not the labels.
Syntax and Examples
The most readable modern approach is to use Object.values() with includes().
Basic syntax
Object.values(MESSAGE_TYPE).includes(value)
Example
export const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
};
const type = 3;
if (Object.values(MESSAGE_TYPE).includes(type)) {
console.log("Valid message type");
}
Why this is clearer
Object.values(MESSAGE_TYPE)gives[1, 2, 3, 4]
Step by Step Execution
Consider this example:
const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
} as const;
const type = 3;
const values = Object.values(MESSAGE_TYPE);
const exists = values.includes(type);
console.log(values);
console.log(exists);
Here is what happens step by step:
-
MESSAGE_TYPEis created as an object:INFOhas value1SUCCESShas value2WARNINGhas value3
Real World Use Cases
Checking whether a value exists in an enum-like object is very common.
API input validation
An API may receive a message type code:
const inputType = Number(req.body.type);
if (!Object.values(MESSAGE_TYPE).includes(inputType)) {
throw new Error("Invalid message type");
}
Form processing
A dropdown may send numeric values as strings:
const selectedType = Number(formData.type);
if (Object.values(MESSAGE_TYPE).includes(selectedType)) {
saveMessageType(selectedType);
}
Configuration checks
A config file may define a status level or logging level:
const level = Number(config.messageType);
if (!.().(level)) {
.();
}
Real Codebase Usage
In real projects, developers usually do not inline this logic everywhere. They wrap it in validation helpers and use patterns that keep the code readable.
Common pattern: validation helper
const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
} as const;
function isMessageType(value: unknown): value is typeof MESSAGE_TYPE[keyof typeof MESSAGE_TYPE] {
return Object.values(MESSAGE_TYPE).includes(Number(value) as typeof MESSAGE_TYPE[keyof typeof MESSAGE_TYPE]);
}
This keeps calling code clean:
if (!isMessageType(type)) {
return;
}
Common Mistakes
1. Checking keys instead of values
This checks property names like "INFO", not numeric values like 1 or 3:
const type = 3;
if (type in MESSAGE_TYPE) {
console.log("exists");
}
Why it is wrong:
inchecks whether a property name exists in the object- the keys are
INFO,SUCCESS,WARNING,ERROR 3is a value, not a key
2. Forgetting type conversion
const type = "3";
console.log(Object.values().());
Comparisons
Here are the common ways to check membership and how they differ.
| Approach | What it checks | Readability | Notes |
|---|---|---|---|
Object.values(obj).includes(value) | Values | High | Best general readable option |
Object.values(obj).indexOf(value) !== -1 | Values | Medium | Older style, works but less clear |
value in obj | Keys | Low for this use case | Wrong if you need to check values |
Object.keys(obj).includes(key) | Keys | High | Useful only for key names |
set.has(value) |
Cheat Sheet
Quick check for values
Object.values(MESSAGE_TYPE).includes(value)
If input may be a string
Object.values(MESSAGE_TYPE).includes(Number(value))
Recommended enum-like object
const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
} as const;
Reusable helper
function isMessageType(value: unknown): boolean {
return Object.values(MESSAGE_TYPE).includes((value));
}
FAQ
How do I check if a number exists in an enum-like object in TypeScript?
Use:
Object.values(MESSAGE_TYPE).includes(value)
This checks whether the value appears in the object's values.
Is in the right operator for this check?
No, not for values. in checks property names, not property values.
Should I use includes() or indexOf()?
Use includes() for readability. It directly expresses the idea of membership.
Why does checking "3" fail when 3 exists?
Because "3" is a string and 3 is a number. includes() uses strict equality.
Do I need Lodash for this?
Usually no. Native JavaScript methods like Object.values() and includes() are enough.
Mini Project
Description
Build a small message type validator that accepts input from an external source and decides whether it is a valid message type. This demonstrates how to validate enum-like values before using them in application logic.
Goal
Create a reusable validator and label function for message type codes.
Requirements
Create an enum-like MESSAGE_TYPE object with four numeric values.
Write a function that checks whether an unknown input is a valid message type.
Convert string inputs like "3" to numbers before validation.
Write a function that returns a readable label for valid message types.
Test the code with valid and invalid inputs.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular formControl Error with Material Autocomplete: Why It Happens and How to Fix It
Learn why Angular says it cannot bind to formControl and how to fix Reactive Forms setup with Angular Material Autocomplete.