如何在TypeScript中使用嵌套对象?解决React+GraphQL项目中“属性nationalPrices不存在于类型object”的错误
嘿,我来帮你搞定这个TypeScript类型的问题!你遇到的报错核心原因很简单:你把prices定义成了宽泛的object类型,TypeScript根本不知道这个对象里包含nationalPrices这些嵌套属性,所以它会报错说找不到这个属性。
咱们需要从最内层的嵌套对象开始,逐层明确每个类型的结构,而不是用object这种模糊的类型。下面是完整的修正方案:
1. 从最基础的价格项开始定义类型
首先,API里的localPrices和regionalPrices数组里的每个元素结构都是一样的,先把这个最基础的类型抽出来:
// 单个价格项的类型 type PriceItem = { pricePerUnit: string; };
2. 定义嵌套的价格分组类型
接下来是包含这些价格项的分组,比如nationalPrices和vendorPrices:
// 全国价格类型 type NationalPrices = { localPrices: PriceItem[]; regionalPrices: PriceItem[]; }; // 供应商价格类型 type VendorPrices = { localPrices: PriceItem[]; };
3. 定义完整的Prices类型
现在把上面两个类型组合成prices对应的完整类型:
type Prices = { nationalPrices: NationalPrices; vendorPrices: VendorPrices; };
4. 修正Product类型
最后,把你的Product类型里的prices从object改成咱们刚定义的Prices,同时注意你之前错误地把nationalPrices放在了Product的顶层,但它其实是prices的子属性,所以要去掉顶层的nationalPrices:
type Product = { code: string; productName: string; prices: Prices; // 这里不再是object,而是明确的Prices类型 };
5. 修正组件里的小问题
另外,我注意到你在渲染的时候用了p.displayName,但API返回的字段是productName,这里会触发另一个类型错误,记得改成p.productName哦!还有React列表渲染需要加key属性,我也一并帮你补上了。
修正后的完整组件代码
// 先定义所有类型 type PriceItem = { pricePerUnit: string; }; type NationalPrices = { localPrices: PriceItem[]; regionalPrices: PriceItem[]; }; type VendorPrices = { localPrices: PriceItem[]; }; type Prices = { nationalPrices: NationalPrices; vendorPrices: VendorPrices; }; type Product = { code: string; productName: string; prices: Prices; }; function ProductList() { const [products, setProducts] = useState<Product[]>([]); const { loading, data, error } = useQuery(LOAD_PRODUCTS); useEffect(() => { if (data) { setProducts(data.products); } }, [data]); return ( <> <div> {products.map(p => ( <div key={p.code}> <ProductCard productName={p.productName} code={p.code} pricePerUnit={p.prices.nationalPrices.localPrices[0].pricePerUnit} /> </div> ))} </div> </> ) }
额外小技巧(适合GraphQL场景)
如果你用GraphQL的话,其实可以用GraphQL Code Generator这个工具,它能根据你的GraphQL查询自动生成对应的TypeScript类型,完全不用手动写,既准确又省时间,非常适合新手避免类型定义错误。
内容的提问来源于stack exchange,提问作者bourne2077

