// O parâmetro de tipo do axios e o `as` sobre `resposta.json()` são a mesma // coisa: uma promessa sua, que o compilador aceita sem conferir. // Retoma a Parte 7 da Extra A ("Dado que veio de fora não tem tipo"). import axios from 'axios'; import { API_URL, descrever, type Livro } from './api.js'; // Erro proposital: /livros/resumo devolve outro formato (id, titulo, // autor.nome e _count), mas o código declara Livro[]. const { data: comAxios } = await axios.get(`${API_URL}/livros/resumo`); const comFetch = (await (await fetch(`${API_URL}/livros/resumo`)).json()) as Livro[]; // Compila sem aviso. Falha só na execução, e longe da chamada que errou. for (const [nome, livros] of [ ['axios', comAxios], ['fetch', comFetch], ] as const) { try { console.log(`${nome}: ISBN com ${livros[0].isbn.length} dígitos`); } catch (erro) { console.log(`${nome}: ${descrever(erro)}`); } } // A garantia real: receber como unknown e verificar na fronteira. function ehLivro(valor: unknown): valor is Livro { if (typeof valor !== 'object' || valor === null) return false; const candidato = valor as Record; const autor = candidato.autor as Record | null | undefined; return ( typeof candidato.id === 'number' && typeof candidato.titulo === 'string' && typeof candidato.isbn === 'string' && typeof candidato.ano === 'number' && typeof autor === 'object' && autor !== null && typeof autor.nome === 'string' ); } function lerLivros(valor: unknown): Livro[] { if (!Array.isArray(valor) || !valor.every(ehLivro)) { throw new TypeError('resposta fora do contrato de Livro[]'); } return valor; } // Com o axios, `data` pode ser declarado como unknown pelo mesmo parâmetro. const { data: bruto } = await axios.get(`${API_URL}/livros/resumo`); try { lerLivros(bruto); } catch (erro) { console.log(`com guarda: ${descrever(erro)} — a falha aparece na chamada que errou`); } const { data: pagina } = await axios.get(`${API_URL}/livros`); // `in` estreita o unknown sem conversão: o envelope também é conferido. const dados = typeof pagina === 'object' && pagina !== null && 'dados' in pagina ? pagina.dados : undefined; console.log(`com guarda: ${lerLivros(dados).length} livros conferidos em GET /livros`);