You fetch user data from an API, and everything looks fine until one field is missing and your app crashes. TypeScript promised safety, but at runtime, things still break. You start wondering: how do I actually check if an object follows an interface?
This problem shows up everywhere, from inputs, API responses, config objects, and utility functions. You define an interface (a TypeScript contract that describes object shape), but you still need a way to verify real objects match it.
In this article, I’ll show you 4 ways to check if an object is an interface in TypeScript.
Method 1 – Use a Type Guard Function
This is the most common and safest way. You create a type guard (a function that tells TypeScript what type an object is at runtime).
Step 1: Define the interface
interface User {
id: number;
name: string;
email: string;
}How does this code work?
The User interface in TypeScript defines the expected structure: three properties with fixed types.
Step 2: Create a type guard function
function isUser(obj: any): obj is User {
return (
typeof obj.id === "number" &&
typeof obj.name === "string" &&
typeof obj.email === "string"
);
}How does this code work?
The return type obj is User is a type predicate. It tells the TypeScript compiler that if this function returns true, then obj should be treated as a User.
Step 3: Use the function
const data: unknown = {
id: 1,
name: "John",
email: "john@example.com",
};
if (isUser(data)) {
console.log(data.name);
}Output:
John
You can see the output in the screenshot below.

How does this code work?
Inside the if block, TypeScript narrows the type of data from unknown to User.
Pro Tip: Always use
unknowninstead ofanyfor external data. It forces you to validate before use.
Method 2 – Use the “in” Operator
This method is quick and useful when you only need to check if required properties exist.
Step 1: Define the interface
interface User {
id: number;
name: string;
email: string;
}Step 2: Check properties using “in”
function isUser(obj: any): obj is User {
return "id" in obj && "name" in obj && "email" in obj;
}How does this code work?
The in operator checks if a property exists in an object. It does not validate the type, only the presence.
Step 3: Use it
const data = { id: 2, name: "Alex", email: "alex@test.com" };
if (isUser(data)) {
console.log("Valid user");
}Output:
Valid user
You can see the output in the screenshot below.

How does this code work?
The function confirms all required keys exist, so TypeScript treats the object as User.
Pro Tip: Combine
"in"withtypeofchecks if you need stronger type safety.
Method 3 – Use Type Assertion (Unsafe Shortcut)
This is a quick approach, but it skips validation. Use it only when you are sure about the data.
Step 1: Define the interface
interface User {
id: number;
name: string;
email: string;
}Step 2: Assert the type
const data = {
id: 3,
name: "Sam",
email: "sam@test.com",
} as User;
console.log(data.name);Output:
Sam
How does this code work?
The as User syntax tells TypeScript to treat the object as a User without checking it.
You can see the output in the screenshot below.

Pro Tip: Avoid this for API data. It can cause runtime errors if fields are missing.
Method 4 – Use a Validation Library (Zod Example)
This is best for production apps. You get runtime validation and strong type inference.
Step 1: Install and import Zod
import { z } from "zod";Step 2: Define schema
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
});How does this code work?
A schema defines validation rules. Zod also generates a TypeScript type from it.
Step 3: Validate object
const data = {
id: 4,
name: "Riya",
email: "riya@test.com",
};
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data.name);
}Output:
Riya
How does this code work?
safeParse checks the object and returns a result object. If validation passes, you get typed data.
Pro Tip: This approach is ideal when working with APIs or user input. It combines runtime checks with compile-time safety.
Things to Keep in Mind
- Interfaces do not exist at runtime: TypeScript removes them during compilation, so you must write manual checks.
- Avoid using any: It disables type safety. Use unknown and validate properly.
- Check types, not just keys: The
"in"operator only checks existence, not correctness of types. - Optional properties can break checks: If your interface has optional fields, handle them carefully in type guards.
- Strict mode matters: Enable
strictin tsconfig for better type checking and safer code. - Type assertion is not validation: It only silences the compiler and can introduce bugs.
You learned four practical ways to check if an object matches an interface in TypeScript.
Use type guards for most cases, validation libraries for production apps, and avoid unsafe assertions unless necessary.
I hope you found this article helpful.
You may also like to read:
- Difference Between Record vs Object in TypeScript
- Difference Between Protected vs Private in TypeScript
- Check if an Object is a String in TypeScript
- Loose vs Strict Equality in TypeScript

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.