Home > Blockchain >  Property does not exist on type when it does in fact exist
Property does not exist on type when it does in fact exist

Time:06-28

I am trying to use Typescript in addition to the fetch API to typify web requests and responses. I have defined an InventoryItem that defines several fields that are returned from the API. Code for InventoryItem looks similar to this:

/src/types/InventoryItem.tsx:

type InventoryItem = {
    id : number;
    upc : string;
    [... And so on ...]
}

Because of the nature of the API I am accessing, I need to make two requests to actually get all of the required data for an inventory item. I am using a function like the following to accomplish this:

async getInventoryItem<InventoryItem>(upc) : InventoryItem | Error {
    let response = await fetch(url, options);
    let firstItem : InventoryItem;
    let secondItem : InventoryItem;

    if (response.ok) {
        let json = await response.json();
        firstItem = json.records[0];

        // Make second request for remaining fields
        response = await fetch(newURL, options);

        if (response.ok) {
            json = await.response.json();
            // Merge important field from first request into second object
            secondItem.upc = firstItem.upc // <--- Issue is here
        }
    }
}

VSCode gives me an error when trying to assign the upc field, claiming that Property 'upc' does not exist on InventoryItem, but as I showed above, said field literally does exist within InventoryItem. Reloading my IDE does not make a difference.

It's most likely that I am doing it all the wrong way, as I have little experience with Typescript. But from what I can tell types are assigned properly. Why can't it find the fields properly?

CodePudding user response:

The type definition type InventoryItem is colliding with the generic type <InventoryItem> that you used in the function defintion. In this case the generic type is overriding the defined type for the scope of this function.

Since you did not constrain the generic type InventoryItem to be of any particular shape, TypeScript can not read property upc since there is no indication that a variable of the generic type InventoryItem should have such property.

It does not look like you really need this generic type. Just removing it should fix the problem.

async getInventoryItem(upc) : InventoryItem | Error {}

If you need the generic type, I would suggest renaming it and constraining it.

async function getInventoryItem<I extends InventoryItem>(upc) : InventoryItem | Error {
    let response = await fetch(url, options);
    let firstItem : I;
    let secondItem : I;

    /* ... */
}

CodePudding user response:

You are inadvertently adding the code for Generics here. Typescript generics is a completely different feature and not required here. But when you do

async getInventoryItem<InventoryItem>(upc)

You have created a new local type (which is used as a variable). This new type is in a sense, overriding the InventoryItem you might have defined outside.

Remove this and you are good

async getInventoryItem(upc) : InventoryItem | Error {

With generics you can create multiple functions like this with different parameter and corresponding return types. I don't think you need that

  • Related