Defined a data type using Typescript, however, the underlying Javascript code is operating with an incorrect data type

Recently delving into Typescript and following along with an educational video. Encountered a strange behavior that seems like a bug. For instance:

const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: number } = JSON.parse(json);

console.log(typeof coordinates.y);

In usual cases, this should display x and y as type numbers. However, the discrepancy is not due to the type declaration but rather the JSON value. If one of them is declared as a string, VS Code interprets it as such although internally it remains a number:

const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: string } = JSON.parse(json);

console.log(typeof coordinates.y);

Here's the code snippet:

https://i.sstatic.net/PnFrM.png

As shown above, VS Code sees it as a string.

https://i.sstatic.net/vj0wt.png

Nevertheless, the type checking indicates otherwise.

In my view, it would make sense for an Object/Array post-parsing to have any type. However, there should be a clear notification of error if the parsed JSON value does not align with your annotation, or it should alter the value to match the annotation accurately.

I'm still a newbie at this, so please correct me if I'm mistaken!

Answer №1

During the compilation process, Typescript performs inference to determine types. If after the compilation to JavaScript some of the type logic in your code is unsound, the declared types may become invalid. This is the issue at hand here.

When using JSON.parse, it returns an object of type any, which can represent anything. Trying to extract properties from it like this:

const coordinates: { x: number; y: string } = JSON.parse(json);

Does not guarantee that the parsed object will actually have an x property as a number or a y property as a string. The compiler is simply instructed to assume these types and treat them accordingly later on.

If you are dealing with something of type any, especially when extracting properties, ensure that the properties match the types you expect. For situations where the input data might be unpredictable (e.g., a network response containing unexpected values), consider implementing a type guard such as:

const isCoordinates = (param: unknown): param is { x: number, y: number } => {
    return typeof param === 'object' && param !== null && 'x' in param;
};

Prior to extracting properties, utilize the isCoordinates function to validate that the data conforms to the expected format.

Otherwise, as demonstrated here, misleading the compiler can result in bugs and unpredictable behavior.

To prevent such mistakes, it is recommended to enable the tslint rule no-unsafe-any.

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

Initiate a click event on an anchor element with the reference of "a href"

I'm currently facing an issue with clicking a href element on my HTML website. The click event doesn't seem to be triggered. CODE: HTML CODE: <div class="button" id="info" ></div> <ul id="game-options"> <li><a ...

Can you always rely on promises being fulfilled?

Consider a scenario where we have a function named logData to handle HTTP requests and another function called logIntoDatabase. async logIntoDatabase(message) { ... } async logData(request, response) { await logIntoDatabase("something happened"); ...

Generate Table Rows with Javascript - produces an excess of cells...>>

I am currently in the process of dynamically creating a table, but I am facing an issue with the number of cells being added. The table I am trying to create has a total of 8 columns (Monday to Friday and a total column at the end). You can view my progr ...

How to efficiently create a unique object on MongoDB during the first instance

In the project I'm working on, there is a feature where a user can create a safe by visiting /mysafe. However, I want this safe to be created only once when they first visit the page. Subsequent visits should redirect them to /mysafe/theidofit. Have ...

Code for a regular expression that permits either letters or numbers with symbols

Here is the code snippet I am using for data validation in jQuery: return /^(?=.*[A-Za-z0-9/\$#.-_])[A-Za-z0-9/\$#.-_]$/i.test(value) The requirement is that the value should begin with letters or numbers, or a combination of both. Afterwards, ...

Leveraging a multi-dimensional JSON array to dynamically populate select options

I'm working on a scenario where I have 2 select boxes - one with static choices and the other being dynamic based on the selection from the first box. I'm using Ajax along with a PHP file that returns multiple arrays, and my goal is to populate t ...

Convert the 'value' attribute in HTML into a clickable link

Is there a way to make the output value of an HTML input field into a clickable link? Right now, it appears as follows: <input type="email" class="form-control" name="contactEmail" value="<?php echo $row_rsContactD ...

AFNetworking failed to correctly deserialise a JSON-encoded dictionary within another dictionary

While working on my PHP backend, I have a situation where I am returning JSON data in the following format: $results_array=array(); $stmt->bind_result($IdUser,$username); while($stmt->fetch()) { $r ...

Retrieve the variance between two arrays and store the additions in AddedList and the removals in RemovedList using typescript

I am still getting the hang of Typescript and I am trying to figure out the best solution for my issue. I have two arrays, A and B, and I need to identify the difference between them in relation to array A. The goal is to separate the elements that were ad ...

What is the reason for jQuery scripts not functioning properly when the scripts are placed above the jQuery library?

this script is functioning correctly: <div class="demo-gallery" data-pswp-uid="1"> <a class = "delete_button">click</a> <script src="https://code.jquery.com/jquery-2.1.4.js"></script> <script> ...

What is the best way to set up a backup plan in case a remote GET request is unsuccessful?

Recently diving into iOS development, I find myself enhancing an existing app by incorporating new features. One such addition requires fetching a JSON file from a web server. However, in the event of server unavailability (no internet connection/server do ...

What is the best way to retrieve a value from an asynchronous function in Node.js?

var fs = require('fs'); var ytdl = require('ytdl-core'); var favicon = require('serve-favicon'); var express = require('express'); var app = express(); app.use(favicon(__dirname + '/public/favicon.png')); ...

Using multiple `setState` calls without synchronization can lead to issues, especially when one of them uses a value obtained from `

In my discovery: When there are two instances of setState The first one is invoked with a value obtained from await Both calls occur in the same thread It results in a scenario where one state is updated while the other remains unchanged. For instance: ...

Changing the appearance of a specific child component in React by referencing its id

There is an interface in my code. export interface DefaultFormList { defaultFormItems?: DefaultFormItems[]; } and export interface DefaultFormItems { id: string; name: string; formXml: string, isDefaultFormEnable: boolean; } I am looking ...

In Angular, when using multiple-selection mode in mat selection, the Error Value should always be in the form of

**Everything is working fine except for one error in the console. How can I remove this error? Can anyone please help me? Save, Edit, and searching are working perfectly fine. ** public campaignCategoryFormGroup$: FormGroup = this.fb.group({ // 'c ...

Guide on implementing std::initializer_list constructor with varying data types for managing nested braced initializers

After exploring the features of the nlohmann json library, I noticed the author's clever method for constructing json objects: json j2 = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothin ...

Creating dynamic JSON endpoints using JSP with Spring MVC

When working with JSON in my webapp, I have successfully passed a variable wordId to the Spring-mvc Controller using a static URL. However, I am unsure of the best practice for dealing with dynamic or parametric URLs. Controller Section: @RequestMapping( ...

Dynamic text displayed on an image with hover effect using JavaScript

Currently, I am in the process of developing a website for a coding course that is part of my university curriculum. The project specifications require the use of JavaScript, so I have incorporated it to display text over images when they are hovered over ...

How can I detect Mongoose events through syntax?

Is there a way to detect the open event in Mongoose based on their documentation located here? According to the documentation, once connected, the open event is fired on the Connection instance. If you're using mongoose.connect, the Connection is m ...

What causes Bootstrap to malfunction when the route contains double slashes?

When using /something, everything works fine, but when switching to /something/somethingelse, Bootstrap fails to function. It seems that the number of "/" characters in the route is causing this issue, rather than the content inside the .ejs file. Here is ...