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.

KeyScreen

Show keypresses on your screen.

ToDoBar

Your to-dos on your menu bar.

SimpleFill

Fill forms using your right-click menu.

IconSim

Preview your Mac app icons.

Ram Patra Published on July 28, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question eslint nextjs November 14, 2024 How to disable ESLint in a Nextjs project?

Although it is highly advisable to enable ESLint at all times, if you do not want ESLint to run during next build, you can set the eslint.ignoreDuringBuilds option in next.config.js to true like below:

question typescript July 28, 2024 Interface vs Type alias in Typescript with some real-world examples showing when to use what

In TypeScript, both interface and type alias can be used to define the shape of an object. However, there are some differences and nuances between them. Here are the key differences:

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.