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