Tengo una pequeña aplicación React/GraphQL que funciona bien, y estoy tratando de agregarle TypeScript, ya que soy nuevo en TypeScript y trato de aprenderlo. Tengo un punto final de la API de GraphQL que devuelve productos e información sobre esos productos. Usando React, almaceno productos en un estado y luego renderizo cada producto usando JSX.
Creé un Product de tipo con la información que espero que devuelva la API, pero también devuelve objetos anidados, y todo lo que probé genera un error de TypeScript. Este es un ejemplo simplificado de lo que devuelve la API:
{ "data": { "products": [ { "productName": "Soda", "code": "sod", "prices": { "nationalPrices": { "localPrices": [ { "pricePerUnit": "1.99" } ], "regionalPrices": [ { "pricePerUnit": "2.49" } ] }, "vendorPrices": { "localPrices": [ { "pricePerUnit": "1.49" } ] } } }, // more products... ] } } Y esta es la solución que tengo actualmente. El code , productName y prices funcionan bien, pero los precios nationalPrices están activando una property nationalPrices does not exist on type 'object' . ¿Qué puedo hacer para corregir este error?
type nationalPricesObject = { localPrices: object[]; } type Product = { code: string; productName: string; prices: object; nationalPrices: nationalPricesObject; } 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> <ProductCard productName={p.displayName} code={p.code} // simplified code below for sake of clearity pricePerUnit={p.prices.nationalPrices.localPrices[0]['pricePerUnit']} /> </div> ))} </div> </> ) }El producto no contiene una propiedad nationalPrices . Product.prices sí. Podemos establecer un tipo Precios que contenga lo que se espera en Producto.precios, y usarlo para definir la propiedad de precios del objeto Producto.
type Prices = { nationalPrices: nationalPricesObject; vendorPrices: someOtherPricesObject; } type Product = { code: string; productName: string; prices: Prices; }El uso del object es complicado en mecanografiado y, en general, no se recomienda. Aquí tienes dos problemas:
object es un tipo ambiguo, por lo que no puede usar precios.Preciosnacionales porque nationalPrices prices.nationalPrices no existen en el tipo de object .localPrices[0] que es de tipo object , no tiene pricePerUnitPara corregir esto, haga que sus tipos sean más específicos:
type nationalPricesObject = { localPrices: { pricePerUnit: number; }[]; // assuming this is number? } type Product = { code: string; productName: string; prices: nationalPricesObject; } Por último, por convención, los tipos en mecanografiado deben ser PascalCase y se deben preferir las interfaces. Entonces, cambiaría tu código para que se vea así:
interface Price { pricePerUnit: number; } interface NationalPrices { localPrices: Price[]; } interface Product { code: string; productName: string; prices: NationalPrices; }