javascripttypescripttypespropertiesinstanceof

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


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!


Solution

  • 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!