I am having trouble with a property that I believe should be recognized but is not

Here is the vocabulary I am working with:

type MyHeaders = {
  Authorization: string;
  Accept: "application/json";
};
type MyGetOptions = {
  url: string;
  json: true;
};
type MyOptionsWithHeaders = {
  headers: MyHeaders;
};
type MyPostOptions<T> = MyGetOptions | {
  body: T;
};
type MyPostOptionsWithHeaders<T> = MyPostOptions<T> | MyOptionsWithHeaders;
type MyBodyType = {};
type APICallOptions = MyPostOptionsWithHeaders<MyBodyType>;

An error is occurring in the following code under the "url" in "temp.url": "Property 'url' does not exist on type 'BatchSubmissionOptions'. Property 'url' does not exist on type 'OptionsWithHeaders'.ts(2339)"

const temp: APICallOptions = {
  url: "url",
  headers: {
    Authorization: "Bearer token",
    Accept: "application/json",
    },
  body: {
    some: "stuff",
    more_stuff: []
  }
}
temp.url = "Hello"

I am attempting to create a vocabulary that allows me to specify arguments like "BatchSubmissionOptions" for a specific query to an internal server API. I want to define options as Post, Post with authentication headers, Get, or Get with authentication headers. The issue arises when trying to set properties after initialization.

Could there be a mistake in my definitions that I am overlooking?

EDIT: Following the recommendation of CodeQuiver, I have adjusted the code with more standardized separators based on the referenced article. Although sound advice, it did not fix the problem at hand.

Side note: While simplifying this problem for the question, I noticed that it doesn't flag an error when the value of "body" doesn't match MyBodyType, allowing different values. It only validates correctly when defining properties in MyBodyType; perhaps this is due to defining an object as {}?

Answer №1

If you have a variable declared with a union type, for example:

let temp: A | B;

You can only access properties that are common to both types when using that variable. This limitation is in place to prevent accessing non-existent properties (which could potentially lead to program crashes) since the compiler cannot determine which specific type the variable will resolve to.

For example:

We have defined two types A and B, each with an overlapping property id:

type A = {
    id: number;
    title: string;
    text: string;
}

type B = {
    id: number;
    flag1: boolean;
    flag2: boolean;
}

The following code snippet will work without any issues:

const id = temp.id;

However, attempting to access a property unique to one of the types will result in an error message:

const text = temp.text;   // <--- Error: "text" does not exist in B

On the other hand, if you assign an object literal, you must include at least one unique property so that the compiler can infer the correct type and warn you about missing properties:

This would throw an error (

Type '{ id: number }' is missing the following properties from type 'B': flag1, flag2
):

let temp: A | B = {
    id: 1
};

To resolve this issue, you need to include additional unique properties so the compiler can determine the appropriate type. For instance, the following declaration specifies type A:

let temp: A | B = {
    id: 1,
    title: "Title"
};

If you don't include the required text property as part of type A, the compiler will raise an error. You can also add properties from type B</code, given that <code>temp is assigned a union type:

let temp: A | B = {
    id: 1,
    title: "Title",
    text: "Text",
    flag1: true
};

Answer №2

It seems like the main issue here is a simple typo. The members of your type literal are not separated properly:

type MyGetOptions = {
  url: string
  json: true
}

In Typescript, you need to separate members using either semicolons or commas, like in this example:

type MyHeaders = {
  Authorization: string,
  Accept: "application/json",
}

This could be why the 'url' property is not being recognized initially.

While there may be more complex issues at play, it's best to address the simpler problem first as it might solve everything. Check out this article for more insights: https://medium.com/swlh/typescript-best-practices-delimiters-and-ordering-7feb42e0ca1d (I couldn't find direct reference to this syntax in the Typescript documentation, so I'm referencing Medium instead, which also uses semicolon separators in its examples.)

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

React component showing historical highchart data when navigating through previous and next periods

I developed this element to showcase a Highchart. It's utilized within a dashboard element that I access from an item in a list. It mostly works as intended, but not entirely. When I move to the dashboard for item A, everything functions correctly. H ...

Utilizing Typescript and sinon to mock the functionalities of jsonwebtoken

Looking for help with mocking the function verify in Typescript's jsonwebtoken library. I've installed typescript, jsonwebtoken, sinon, mocha, and chai along with their corresponding types. However, when trying to stub the function, an error occu ...

Tips for adding a border to a table cell without disrupting the overall structure of the table

Looking for a way to dynamically apply borders to cells in my ng table without messing up the alignment. I've tried adjusting cell width, but what I really want is to keep the cells' sizes intact while adding an inner border. Here's the sim ...

Angular's AsyncValidatorFn is triggered by the onblur event and does not work with keypress events

I'm currently working with the latest version of Angular and I'm attempting to implement a custom validation for checking a code through a RestAPI. The example below is functional, but it doesn't trigger on keypress events; it only activates ...

The field '_id' is not present in the type Pick

I'm working on a project using Next.js and attempting to query MongoDB with TypeScript and mongoose, but I keep encountering a type error. types.d.ts type dbPost = { _id: string user: { uid: string name: string avatar: string } po ...

Create a series of actions that do not depend on using only one occurrence of the WriteBatch class

My goal is to create a series of batch actions using functions that do not require a specific instance of WriteBatch. Currently, I am passing an instance of the WriteBatch class to the functions so they can utilize the .set(), .update(), or .delete() metho ...

React-table fails to show newly updated data

I am facing an issue with my react-table where real-time notifications received from an event-source are not being reflected in the table after data refresh. https://i.stack.imgur.com/q4vLL.png The first screenshot shows the initial data retrieval from th ...

Ways to change a value into int8, int16, int32, uint8, uint16, or uint32

In TypeScript, the number variable is floating point by default. However, there are situations where it's necessary to restrict the variable to a specific size or type similar to other programming languages. For instance, types like int8, int16, int32 ...

Is there a way to remove a dynamically rendered component from a list?

Whenever I click a button, the same component is dynamically rendered on top of the list. But now, I need to implement a feature where users can delete any component from the list by clicking a cancel button associated with each component. Here's my ...

What is the best way to create TypeScript declarations for both commonjs modules and global variables?

Wanting to make my TypeScript project compatible with both the commonjs module system and globals without modules. I'm considering using webpack for bundling and publishing it into the global namespace, but running into issues with the definitions (.d ...

Exploring table iteration in Angular 7

I am looking to create a table with one property per cell, but I want each row to contain 4 cells before moving on to the next row... This is what I want: <table> <tr> <td> <mat-checkbox>1</mat-checkbox& ...

What could be causing the lack of updates for my service on the app component?

I am currently using Ionic 4 and facing an issue with displaying information about the logged-in user. The code works perfectly in all components except for the app component. I have a variable named userData which is a BehaviorSubject. Can someone help me ...

Automatically adjust padding in nested lists with ReactJS and MaterialUI v1

How can I automatically add padding to nested lists that may vary in depth due to recursion? Currently, my output looks like this: https://i.stack.imgur.com/6anY9.png: However, I would like it to look like this instead: https://i.stack.imgur.com/dgSPB. ...

The main module's postinstall process is initiated before the sub-module's postinstall process

Update: I am seeking guidance on how to install a module from GitHub instead of npm. That's the main query. In case you're wondering why: I'm currently working on some confidential projects and prefer not to publish the code. As a result, ...

The SetInterval function will continue to run within a web component even after the corresponding element has been removed from the

I am currently engaged in developing a straightforward application that coordinates multiple web components. Among these components, there is one that contains a setInterval function. Interestingly, the function continues to run even after the component it ...

Hold on until the page is reloaded: React

My current setup includes a React Component that contains a button. When this button is clicked, a sidePane is opened. What I want to achieve is refreshing the page first, waiting until it's completely refreshed, and then opening the sidepane. Below i ...

An error occurred while defining props due to a parsing issue with the prop type. The unexpected token was encountered. Perhaps you meant to use `{`}` or `}`?

const dataProps = defineProps({ selectedData: <Record<string, string>> }); Under the closing bracket, there is a red line indicating: Error: Unexpected token. Consider using {'}'} or &rbrace; instead?eslint Expression expecte ...

Angular 6 combined with Firebase is experiencing difficulties with routing after a successful login

After spending hours trying to fix my issue, I still can't figure it out. I've searched through related threads on SO, but haven't found a solution yet. Issue After successfully signing up, the email verification flag is set to true. Howev ...

Utilizing Session storage throughout an Angular 2 application

I currently store a session variable as a JSON value in my home.component.ts. This variable needs to be accessed in various locations within the application. This is my code snippet: .do(data => sessionStorage.setItem('homes', JSON.stringif ...

Get a list of images by incorporating NextJs and Strapi to create a dynamic slider feature

[] I need help creating a slider as I am encountering an error when trying to output an array of objects. The error can be seen here: . Can someone assist me in resolving this issue? Thank you. Here is a screenshot from the admin panel: 1 Below is the c ...