typescript's JSON.stringify function includes internal fields but omits public interface values

I'm currently grappling with some confusion surrounding serialization in TypeScript using JSON.stringify and interfaces. My goal is to create an export format for serializing certain objects back to their server-side representation, focusing solely on base type data and excluding methods.

I've come across information suggesting that interfaces offer a convenient way to export to JSON, but I'm struggling to grasp the process.

Here's a basic example of my attempted approach:

interface PublicFoo {
  name: string,
  age: number
}

class Foo implements PublicFoo {
    private _name : string;
    private _age : number;
    private _pin : number;

    constructor(name : string, age : number, pin: number) {
        this._name = name;
        this._age = age;
        this._pin = pin;
    }
    get name() {
        return this._name;
    }
    get age() :number {
        return this._age;
    }
    get pin() : number {
        return this._pin;
    }
    serialize() : string {
        let pubFoo : PublicFoo = this;
        return (JSON.stringify(pubFoo));
    }
}

My hope was that by running this code:

let foo = new Foo("George", 27, 3918);
console.log(foo.serialize());

I would receive output like this:

{"name":"George","age":27}

However, instead of the expected result, I got:

{"_name":"George","_age":22,"_pin":3239}

This outcome displays private field names, including those I do not wish to serialize and are not part of the PublicFoo interface.

What is the correct approach to achieve this without manually constructing the export? The ability to simply stringify the object is appealing due to its convenience, especially when dealing with large and complex objects...

Answer №1

Getters don't seem to be considered in the stringify process.
The question of whether or not TypeScript should utilize hints from interfaces to automatically populate serializations using getters is a separate matter, considering that interfaces are not present in plain JavaScript and therefore do not have default behavior to inherit.

To address this issue, simply add a toJSON() function and update your serialization method to use it:

toJSON = () :PublicFoo => ({name:this._name, age:this._age});

serialize = () :string => (JSON.stringify(this));

It's important to keep in mind that TypeScript primarily serves as a typing system to assist developers; at its core, it is still JavaScript.
Nothing remains truly private


In response to your comment, consider utilizing reflection to incorporate compile-time information into runtime

import {keys} from 'ts-transformer-keys';

function freeze<Interface extends object>(instance :Interface) :Interface {
    let output :Interface = {} as any;
    for (let property of keys<Interface>())
        output[property] = instance[property];
    return output;
}

Then update the toJSON function mentioned above to:

toJSON = () :PublicFoo => (freeze<PublicFoo>(this));

Answer №2

It's important to keep in mind that typescript doesn't offer any functionality during runtime, contrary to what you might think. Its main purpose is to ensure type safety at compile time. Therefore, if you want to understand how your typescript code will behave, you need to examine the javascript it gets compiled into. Retrieval methods are essentially functions that return a value, just like any other function. So, naturally, when serializing an object, you won't see the values returned by these functions. How can you address this issue? Unfortunately, you'll have to create your own serialization method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for extending props from React.HTMLProps<HTMLButtonElement>?

"react": "^17.0.2", "typescript": "^4.2.4" Can someone help me understand how to extend props from React.HTMLProps? import { FC, HTMLProps } from 'react' export interface SliderButtonProps extends HTMLPro ...

Avoid navigating to the subscribe block when the server sends a response in Angular

When trying to send a request to the server and check the response, I am not seeing any results. The code for sending the request is below: SendVerificationInfo(item: SendVerificationModel): Observable < any > { return this.httpClient.post < any ...

Unable to access data encoded in JSON format

After querying the database using a Model, I attempted to retrieve certain data. echo $user = User::whereRaw('username = ? and password = ?', array($username,$password))->get(); The returned data is in JSON format: [{"id":1,"name":"Abhijith ...

Customizing Axis2-JSON within the WSO2 ESB platform

I need to address a JSON parsing issue in axis2-json that is part of WSO2 ESB. The specific file causing the error is located at: ./repository/components/plugins/axis2-json-1.6.1.wso2v4.jar It seems like there have been some customizations made. What are ...

What is the best way to transform an Observable array containing objects into an Observable that emits the data contained within those objects?

Encountering an error: Error: Type 'Observable<Country[]>' is not assignable to type 'Observable'. Type 'Country[]' is missing properties like name, tld, alpha2Code, alpha3Code and more.ts(2322 The issue might be due ...

In search of JSON data containing intricate details about Dota 2 heroes and items

Currently, I am developing an application that interacts with the steam API to retrieve data. I have made progress on my project but require assistance in obtaining detailed information on Dota2 heroes or items that include 'id', 'name' ...

Mapping type property names in Typescript for substitution

I am working on a function that accepts two objects as parameters: one representing a model and the other representing a mapping. The function then returns an object with two properties: one showing the base model and the other displaying the model with ea ...

React textarea trigger function on blur event

https://codesandbox.io/s/react-textarea-callback-on-blur-yoh8n?file=/src/App.tsx When working with a textarea in React, I have two main objectives: To remove focus and reset certain states when the user presses "Escape" To trigger a callback function (sa ...

Convert the output of SQLAlchemy into a JSON format that includes the names of the columns

I have made the decision to transition my Django project from using Django ORM to SqlAlchemy. I am currently working on serializing the SqlAlchemy output to JSON, which includes column names. In my previous Django code, I had: logs = Log.objects.values(& ...

In order to use the serve command, it is necessary to run it within an Angular project. However, if a project definition cannot be located

An error occurred while running the ng serve command: C:\Mysystem\Programs\myfwms>ng serve The serve command needs to be executed within an Angular project, but a project definition could not be found. I encounter this error when ...

Guide on creating a style instance in a component class using Material-UI and Typescript

After transitioning my function component to a class component, I encountered an error with makeStyle() from Material-UI as it violates the Rule of Hooks for React. The documentation for Material-UI seems to focus mainly on examples and information related ...

Jackson Library - com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

Upon attempting to deserialize the Automobile class, I encounter an error where Jackson is searching for a field in the child element within the parent class. How can I ensure that Jackson uses the appropriate child type for deserialization? It seems like ...

A node is receiving a JSON object through an axios POST request

I am working on a project where I have two unique URLs. The first URL receives a form action from an HTML page along with data and then makes a post request to the second URL. The second URL, in turn, receives a JSON and uses Express to make a GET request ...

How to generate a fresh JSON file by extracting unique elements from a JSON array using PHP

I have a JSON object that resembles the following: OBJECT $deals [ { "deal_id": 124563 "merchant_id": 123 "merchant_name": Merchant1 } { "deal_id": 456789 "merchant_id": 123 "merchant_name": Merchant1 } { "deal_id": ...

What is the best way to loop through the contents of this JSON document?

I am looking to create my resume using React. I have a JSON file that includes all my work experience, education, and more. However, I am facing an issue with the way the data is displayed. { "experience":[ { "Title":"Previous Job ...

Saving data into JSON file was unsuccessful due to incorrect ordering of the entries

Currently, I am developing a desktop application using QT C++ that is responsible for converting a text file into a JSON file. Here is an example of the desired output: { "102": { "NEUTRAL": { "blend": ...

Exploring Laravel Eloquent using JSON and iteration methods

I need to extract specific fields from news articles and convert them into JSON format. My attempt to loop through all the news articles using this code: public function appNews() { $news = News::orderBy('id', 'desc')->get(); ...

Creating a custom listview in Android to display JSON data

I encountered an issue while attempting to populate a custom listview with JSON data. Upon running the app, only a blank layout file is displayed. The JSON source can be found at Below is the code snippet of what I have implemented: This is the main act ...

What is the best method for converting a geopandas dataframe containing multi-polygons into geojson format?

Currently, I am working with a Geopandas data frame that contains multi-polygon geometries. My goal is to convert this data frame into geojson format. To do so, I initially converted the dataframe into a dictionary and then utilized json.dump(dict) to tran ...

Improving type definitions in Typescript 2.6 using module augmentation leads to error TS2339: Property '' is not found on type ''

Currently utilizing the material-ui library version v1.0.0-beta. An update was released yesterday to v1.0.0-beta.28, however, the type definitions were not updated resulting in runtime errors while compilation remains successful. Encountering this error i ...