Loading...

How to pass a generic JSON object as a parameter to a method in TypeScript?

question typescript
Ram Patra Published on July 28, 2024

If you want to allow any JSON object without specifying its structure, you can use the object type, Record<string, any>, or simply any. However, each approach has its own implications for type safety and flexibility.

Using the object Type

The object type is used to represent non-primitive types, i.e., anything that is not a number, string, boolean, symbol, null, or undefined. However, it doesn’t provide type safety for the object’s properties.

function processJsonObject(json: object) {
    console.log(json);
}

const jsonObject = {
    name: "John Doe",
    age: 25,
    isStudent: true
};

processJsonObject(jsonObject);

Using Record<string, any>

The Record<string, any> type represents an object with string keys and values of any type. This is more flexible than the object type and allows you to access properties without TypeScript errors.

function processJsonObject(json: Record<string, any>) {
    console.log(json);
    console.log(json.name); // This is allowed
}

const jsonObject = {
    name: "John Doe",
    age: 25,
    isStudent: true
};

processJsonObject(jsonObject);

Using any

The any type can be used to represent any JavaScript value. It disables type checking for the parameter, making your function accept any type of input, including non-object types.

function processJsonObject(json: any) {
    console.log(json);
    console.log(json.name); // This is allowed, but type checking is disabled
}

const jsonObject = {
    name: "John Doe",
    age: 25,
    isStudent: true
};

processJsonObject(jsonObject);

Using unknown

If you want to allow any type but still maintain some type safety, you can use the unknown type. This forces you to perform type checks before accessing properties, making your code safer.

function processJsonObject(json: unknown) {
    if (typeof json === "object" && json !== null) {
        const jsonObj = json as Record<string, any>;
        console.log(jsonObj);
        console.log(jsonObj.name); // This is allowed after type assertion
    } else {
        console.log("Invalid JSON object");
    }
}

const jsonObject = {
    name: "John Doe",
    age: 25,
    isStudent: true
};

processJsonObject(jsonObject);

Conclusion

  • object: Use when you want to ensure the parameter is an object but don’t need to access its properties directly.
  • Record<string, any>: Use when you need flexibility to access properties while allowing any JSON structure.
  • any: Use when you don’t need type safety and want maximum flexibility.
  • unknown: Use when you want to allow any type but still enforce type checks within the function for safer code.

Depending on your use case and the level of type safety you need, you can choose the appropriate type for your generic JSON object parameter.

Presentify

Take your presentation to the next level.

FaceScreen

Put your face and name on your screen.

ToDoBar

Your to-dos on your menu bar.

Ram Patra Published on July 28, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question typescript July 20, 2024 How to filter a Map based on a condition in Typescript?

In TypeScript, you can filter a Map based on a condition using the Map’s built-in methods along with some of JavaScript’s array methods. Since Map is iterable, you can convert it to an array, apply the filter, and then convert it back to a Map. Here’s how you can do it:

question typescript March 26, 2025 ES6 vs ES2020 vs ESNext modules and which one should you use

The difference between ESNext, ES6/ES2015, ES2020, and other module options in TypeScript is mainly about which ECMAScript version’s module system is used. Here’s a breakdown:

question typescript react September 28, 2024 How to add a custom element to a Next.js/Typescript project?

Let’s say I have a custom element setapp-badge that I want to use in my tsx files. If I go ahead and use it, the compiler will throw an error and Next.js will fail to build. It seems the problem might be a combination of how Next.js, TypeScript, and custom elements work together. Therefore, let’s try an approach that avoids the namespace/module issues while ensuring custom elements are recognized in a Next.js/TypeScript project.

Like my work?

Please, feel free to reach out. I would be more than happy to chat.