In TypeScript, how to generally check the instanceof of an object variable?

153 Views Asked by At

I want to check if the obj object variable has all the properties of the Person interface.

interface Person {
  name: string;
  age: number;
}

const jsonObj = `{
  name: "John Doe",
  age: 30,
}`;

const obj: Person = JSON.parse(jsonObj);

const isPerson = obj instanceof Person; // Person is not defined

console.log(isPerson); // true

When I execute this code, it yield Person in not defined!

I would expect the code to log true as the obj is an instance of Person.

  -----




Answer Update: Alternative Working Solution Using zod Library

TypeScript works only in compile-time, but instanceof is a runtime thing. You can't use on a type, because types doesn't exist in javascript.

You can use a validator library like zod. Then, you can infer the ("TypeScript") type of the object and validate it with zod.

Per example,

import { z } from 'zod';

export const ItemSchema = z.object({
  name: z.string(),
  description: z.string(),
  productServiceId: z.number().optional(),
});

export type Item = z.infer<typeof ItemSchema>;

const validateItems = (items: Item[]) => {
    const ItemSchemaArray = z.array(ItemSchema);
    // This line below will throw an error if the validation failed
    ItemSchemaArray.parse(items);
};

Konrad referenced this library in the comments below.

Thank you, @Konrad!

2

There are 2 best solutions below

2
Jörg W Mittag On BEST ANSWER

interfaces are a static TypeScript feature. instanceof is a dynamic ECMAScript operator. interfaces do not exist at runtime, and ECMAScript does not know anything about TypeScript types.

Therefore, you cannot test at runtime whether an object conforms to an interface.

You can use a validator library like zod. Then, you can infer the ("TypeScript") type of the object and validate it with zod.

Per example,

import { z } from 'zod';

export const ItemSchema = z.object({
  name: z.string(),
  description: z.string(),
  productServiceId: z.number().optional(),
});

export type Item = z.infer<typeof ItemSchema>;

const validateItems = (items: Item[]) => {
    const ItemSchemaArray = z.array(ItemSchema);
    // This line below will throw an error if the validation failed
    ItemSchemaArray.parse(items);
};

Konrad referenced this library in the comments above.

Thank you, @Konrad!

2
Jonel Albuquerque On

You can create a type guard function that checks if the object adheres to the types set out in the interface. So: function isPerson(obj: any): obj is Person { return obj && typeof obj.name === 'string' && typeof obj.age === 'number'; } will return true or false if either of the parameters are not the types specified. You will then change your console log to console.log(isPerson(obj));