TypeScript报属性不存在错误但对应类型中已实际定义该字段
报错根因
你遇到的类型识别错误是类型遮蔽导致的:
你写的函数签名async getInventoryItem<InventoryItem>(upc) : InventoryItem | Error里,尖括号包裹的<InventoryItem>是你在函数作用域内声明的一个全新泛型类型参数,它和你在/src/types/InventoryItem.tsx中定义的固定结构类型完全无关,只是恰好重名,直接把外层的自定义类型遮蔽了。
这个无任何约束的泛型参数本质上和unknown类型一致,TS自然无法从上面找到你定义的upc字段,重载IDE当然解决不了这个写法错误。
修复步骤
- 移除错误的泛型声明
你的场景不需要泛型,函数返回值是固定的InventoryItem结构,直接删掉尖括号部分即可。另外注意异步函数的返回值必须包裹在Promise类型中,你之前的返回值类型写法不符合TS规范:// 错误写法 // async getInventoryItem<InventoryItem>(upc) : InventoryItem | Error { // 正确写法 async getInventoryItem(upc: string): Promise<InventoryItem | Error> { - 修正代码里的其他语法问题
await.response.json()多写了一个点,正确写法是await response.json()secondItem只声明未赋值就直接修改属性,TS会报"变量在赋值前被使用"的错误,建议直接从接口返回值取数后做对象合并,不要先声明空变量- 函数所有分支需要有明确返回值,否则返回类型会隐式包含
undefined
修正后参考实现
// 先导入你定义的类型 import type { InventoryItem } from '/src/types/InventoryItem.tsx'; async function getInventoryItem(upc: string): Promise<InventoryItem | Error> { try { // 第一次请求拿upc等基础字段 const firstRes = await fetch(firstRequestUrl, options); if (!firstRes.ok) throw new Error(`First request failed with status ${firstRes.status}`); const firstData = await firstRes.json(); const baseItem = firstData.records[0] as Pick<InventoryItem, 'upc'>; // 第二次请求拿剩余字段 const secondRes = await fetch(secondRequestUrl, options); if (!secondRes.ok) throw new Error(`Second request failed with status ${secondRes.status}`); const detailItem = await secondRes.json() as Omit<InventoryItem, 'upc'>; // 合并后返回完整结构 return { ...detailItem, upc: baseItem.upc }; } catch (e) { return e instanceof Error ? e : new Error(String(e)); } }
补充提示
如果后续你确实需要给这类函数加泛型支持,注意不要让泛型参数名和已定义的类型重名,同时给泛型加约束避免类型丢失,比如:
// 泛型T必须满足InventoryItem的结构要求 async function getInventoryItem<T extends InventoryItem>(upc: string): Promise<T | Error> { // 内部逻辑 }
内容的提问来源于stack exchange,提问作者user17615929
相关产品推荐
相关产品推荐

