Question
How can I determine whether a variable is a string or another type in JavaScript? For example, I want to reliably check whether a value is a string before using string-specific methods on it.
Short Answer
By the end of this page, you will understand how JavaScript represents strings, how to test whether a value is a string, and which approaches are safest in real code. You will also see common mistakes, practical examples, and how developers usually handle type checks in applications.
Concept
In JavaScript, a string is a sequence of characters such as "hello" or 'abc'. Strings are one of JavaScript's primitive types.
The most common way to check whether a value is a string is with typeof:
typeof value === "string"
This works well for normal string values because JavaScript reports primitive strings as "string".
Why this matters
In real programs, values often come from:
- user input
- APIs
- form fields
- configuration files
- function arguments
Before calling string methods like .toLowerCase(), .trim(), or .includes(), it is often a good idea to confirm that the value is actually a string. Otherwise, your code may throw errors such as:
TypeError: value.trim is not a function
Primitive strings vs String objects
JavaScript has two related but different forms:
const a = "hello"; // primitive string
const b = new String("hello"); // String object
Most of the time, you should use primitive strings. new String() creates an object wrapper, which behaves differently and can cause confusion.
For this reason, typeof is usually the best check for everyday JavaScript:
typeof a === "string" // true
typeof b === "string" // false
If you need to accept both primitive strings and String objects, you can combine checks:
typeof value === "string" || value instanceof String
That said, in beginner and production code, avoiding new String() is usually the better choice.
Mental Model
Think of JavaScript values as items in labeled boxes.
- A primitive string is a simple note with text written on it.
- A
Stringobject is a note placed inside a container.
If you ask JavaScript typeof, it tells you the label on the outside:
- primitive string →
"string" Stringobject →"object"
So if you only want normal text values, typeof is enough. If you also want to allow wrapped text inside a container, you need an extra check.
Syntax and Examples
The most common syntax is:
typeof value === "string"
Example 1: Basic string check
const name = "Ada";
if (typeof name === "string") {
console.log("name is a string");
} else {
console.log("name is not a string");
}
This prints:
name is a string
Example 2: Non-string value
const age = 42;
console.log(typeof age === "string");
Output:
false
Example 3: Accept primitive strings and String objects
function isString(value) {
return typeof value === "string" || value instanceof String;
}
console.log(isString("hello")); // true
console.log(isString(new String("hello"))); // true
console.log(isString(123)); // false
console.log(isString(null)); // false
Example 4: Safe use before calling a string method
function printLowerCase(value) {
if (typeof value === "string") {
console.log(value.toLowerCase());
} else {
console.log("Value is not a string");
}
}
printLowerCase("HELLO");
printLowerCase(100);
This avoids runtime errors by checking the type first.
Step by Step Execution
Consider this example:
function describeValue(value) {
if (typeof value === "string") {
console.log("String: " + value.toUpperCase());
} else {
console.log("Not a string");
}
}
describeValue("cat");
describeValue(10);
Step by step:
-
The function
describeValueis defined with one parameter:value. -
describeValue("cat")is called. -
Inside the function, JavaScript evaluates:
typeof value === "string" -
Since
valueis"cat",typeof valuebecomes"string". -
The condition is
true, so the first block runs. -
value.toUpperCase()becomes"CAT". -
The console prints:
String: CAT -
Next,
describeValue(10)is called. -
Now
typeof valuebecomes"number". -
The condition is
false, so theelseblock runs. -
The console prints:
Not a string
This is a simple pattern: check first, then safely use string methods.
Real World Use Cases
Checking whether a value is a string is useful in many real situations.
Form handling
function normalizeUsername(username) {
if (typeof username !== "string") return "";
return username.trim().toLowerCase();
}
This protects your code if a bad value is passed in.
API response validation
function readMessage(data) {
if (typeof data.message === "string") {
return data.message;
}
return "No message available";
}
APIs do not always return the shape you expect.
Command-line scripts
function processArgument(arg) {
if (typeof arg === "string") {
console.log("Argument length:", arg.length);
}
}
Filtering data
const values = ["apple", 10, null, "banana", true];
const onlyStrings = values.filter(value => typeof value === "string");
console.log(onlyStrings); // ["apple", "banana"]
Defensive programming in utility functions
function startsWithA(value) {
return typeof value === "string" && value.startsWith("A");
}
This prevents errors when unexpected input appears.
Real Codebase Usage
In real codebases, developers often use string checks as part of validation and guard clauses.
Guard clauses
A guard clause exits early when the input is invalid.
function formatTitle(title) {
if (typeof title !== "string") {
return "Untitled";
}
return title.trim();
}
This keeps the rest of the function simpler.
Input validation
function createUser(data) {
if (typeof data.name !== "string") {
throw new Error("name must be a string");
}
return {
name: data.name.trim()
};
}
Filtering collections
const mixed = ["x", 1, "y", {}, "z"];
const strings = mixed.filter(item => typeof item === "string");
Configuration checks
function loadConfig(config) {
if (typeof config.apiUrl !== "string") {
throw new Error("apiUrl must be a string");
}
}
Error-safe property usage
function safeTrim(value) {
if (typeof value !== "string") return value;
return value.trim();
}
In practice, typeof value === "string" is the default pattern. Broader checks are used only when there is a strong reason to support String objects.
Common Mistakes
1. Using instanceof String by itself
This misses normal primitive strings.
console.log("hello" instanceof String); // false
console.log(new String("hello") instanceof String); // true
Why it happens:
"hello"is a primitive, not an object.
Better approach:
typeof value === "string"
2. Forgetting about new String()
const value = new String("hello");
console.log(typeof value); // "object"
If your code only checks typeof value === "string", this object will not pass.
Avoid creating strings this way unless you have a special reason.
3. Calling string methods without checking
Broken code:
function clean(value) {
return value.trim();
}
clean(123); // error
Safer version:
function clean(value) {
if (typeof value !== "string") return "";
return value.trim();
}
4. Confusing strings with other printable values
const value = 100;
console.log(String(value)); // "100"
This converts a value to a string, but it does not mean the original value was a string.
5. Checking truthiness instead of type
Broken idea:
if (value) {
console.log("must be a string");
}
This only checks whether the value is truthy. Numbers, arrays, and objects can also be truthy.
Use an actual type check instead.
Comparisons
| Check | What it does | Works for primitive strings | Works for new String() | Recommended |
|---|---|---|---|---|
typeof value === "string" | Checks whether the value is a primitive string | Yes | No | Yes |
value instanceof String | Checks whether the value is a String object | No | Yes | Rarely |
| `typeof value === "string" | value instanceof String` | Accepts both forms | Yes | |
Object.prototype.toString.call(value) === "[object String]" | More explicit internal tag check | Yes | Yes | Useful in edge cases |
typeof vs instanceof
console.log(typeof "hi"); // "string"
console.log("hi" instanceof String); // false
console.log(typeof new String("hi")); // "object"
console.log(new String("hi") instanceof String); // true
Which one should you use?
- Use
typeof value === "string"for normal JavaScript code. - Use a combined check only if you must support
Stringobjects. - Avoid
new String()in most code.
Cheat Sheet
Quick check
typeof value === "string"
Accept both primitive strings and String objects
typeof value === "string" || value instanceof String
Common results
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof null // "object" (historical quirk)
typeof undefined // "undefined"
typeof new String("hello") // "object"
Safe helper function
function isString(value) {
return typeof value === "string";
}
Broader helper
function isAnyString(value) {
return typeof value === "string" || value instanceof String;
}
Rule of thumb
- Prefer primitive strings like
"text" - Avoid
new String("text") - Check before calling string methods on unknown input
FAQ
How do I check if a variable is a string in JavaScript?
Use:
typeof value === "string"
This is the standard and most common solution.
Why does instanceof String return false for normal strings?
Because normal strings are primitive values, not String objects. instanceof only works with objects created from constructors.
Should I use new String() in JavaScript?
Usually no. It creates a wrapper object instead of a primitive string, which can lead to confusing behavior.
Can I safely call .trim() after checking with typeof?
Yes, if typeof value === "string" is true, then string methods like .trim() are safe to use.
How do I check for both primitive strings and String objects?
Use:
typeof value === "string" || value instanceof String
Is null a string in JavaScript?
No. null is not a string. Note that typeof null returns "object", which is a long-standing JavaScript quirk.
What is the safest approach in real applications?
Use typeof value === "string" for normal validation, and add fallback handling when the value is not a string.
Mini Project
Description
Build a small utility that safely formats user-provided text. This project demonstrates how to check whether a value is a string before using string methods such as trim() and toUpperCase(). This is useful in real applications where input may come from forms, APIs, or other untrusted sources.
Goal
Create a function that accepts any value and returns a cleaned uppercase string only when the input is actually a string.
Requirements
- Create a function named
formatInput. - If the input is not a string, return
"Invalid input". - If the input is a string, remove extra spaces with
trim(). - Convert valid string input to uppercase.
- Test the function with a string, a number, and
null.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.