Desafio TypeScript
Sistema de biblioteca com tipos e readonly
Enunciado
Crie um type alias Livro com:
isbn: string (readonly)titulo: stringautor: stringanoPublicacao: number (opcional)disponivel: boolean (opcional, padrãotrue)
Crie um type alias Biblioteca que seja um array de Livro.
Implemente as funções:
adicionarLivro(biblioteca: Biblioteca, livro: Livro): Biblioteca— retorna uma nova biblioteca com o livro adicionado (não modifique o array original).buscarLivroPorIsbn(biblioteca: Biblioteca, isbn: string): Livro | undefined— retorna o livro com o ISBN correspondente ouundefined.listarLivrosDisponiveis(biblioteca: Biblioteca): string[]— retorna um array com os títulos dos livros disponíveis (considerandodisponivelpadrãotrue).
Teste criando uma biblioteca, adicionando livros, buscando por ISBN e listando disponíveis.
Requisitos
- Definir os tipos
LivroeBibliotecaconforme especificado. isbndeve ser readonly.adicionarLivrodeve retornar um novo array (imutabilidade).buscarLivroPorIsbndeve retornarLivro | undefined.listarLivrosDisponiveisdeve considerardisponivelpadrãotrue.
Código inicial
// Defina os tipos e implemente as funções
type Livro = {
// complete aqui
};
type Biblioteca = Livro[];
function adicionarLivro(biblioteca: Biblioteca, livro: Livro): Biblioteca {
// complete aqui
}
function buscarLivroPorIsbn(biblioteca: Biblioteca, isbn: string): Livro | undefined {
// complete aqui
}
function listarLivrosDisponiveis(biblioteca: Biblioteca): string[] {
// complete aqui
}
// Testes
let minhaBiblioteca: Biblioteca = [];
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '123', titulo: 'Livro A', autor: 'Autor X' });
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '456', titulo: 'Livro B', autor: 'Autor Y', disponivel: false });
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '789', titulo: 'Livro C', autor: 'Autor Z', anoPublicacao: 2020 });
console.log(buscarLivroPorIsbn(minhaBiblioteca, '456'));
console.log(listarLivrosDisponiveis(minhaBiblioteca));
Saída esperada
{ isbn: '456', titulo: 'Livro B', autor: 'Autor Y', disponivel: false }
[ 'Livro A', 'Livro C' ]
Ver dica
Use readonly em isbn. Para adicionarLivro, use spread operator: [...biblioteca, livro]. Para disponivel, verifique se é undefined e assuma true.
Mostrar solução
type Livro = {
readonly isbn: string;
titulo: string;
autor: string;
anoPublicacao?: number;
disponivel?: boolean;
};
type Biblioteca = Livro[];
function adicionarLivro(biblioteca: Biblioteca, livro: Livro): Biblioteca {
return [...biblioteca, livro]; // novo array, não modifica o original
}
function buscarLivroPorIsbn(biblioteca: Biblioteca, isbn: string): Livro | undefined {
return biblioteca.find(livro => livro.isbn === isbn);
}
function listarLivrosDisponiveis(biblioteca: Biblioteca): string[] {
return biblioteca
.filter(livro => livro.disponivel ?? true) // padrão true se undefined
.map(livro => livro.titulo);
}
// Testes
let minhaBiblioteca: Biblioteca = [];
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '123', titulo: 'Livro A', autor: 'Autor X' });
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '456', titulo: 'Livro B', autor: 'Autor Y', disponivel: false });
minhaBiblioteca = adicionarLivro(minhaBiblioteca, { isbn: '789', titulo: 'Livro C', autor: 'Autor Z', anoPublicacao: 2020 });
console.log(buscarLivroPorIsbn(minhaBiblioteca, '456'));
console.log(listarLivrosDisponiveis(minhaBiblioteca));
Passo a passo
- Definimos
Livrocomisbnreadonly,tituloeautorobrigatórios, eanoPublicacaoedisponivelopcionais. Bibliotecaé um alias paraLivro[].adicionarLivrousa spread operator para criar um novo array com o livro adicionado, preservando a imutabilidade.buscarLivroPorIsbnusaArray.findpara localizar o livro pelo ISBN, retornandoLivro | undefined.listarLivrosDisponiveisfiltra livros ondedisponivelétrueouundefined(usando?? true), e mapeia para os títulos.- Nos testes, criamos uma biblioteca vazia, adicionamos três livros e chamamos as funções.
- Imprimimos o resultado da busca e a lista de disponíveis.
Por que funciona
O type alias Livro garante que cada objeto tenha a forma correta, com isbn imutável. As funções operam de forma pura: adicionarLivro não modifica o array original, buscarLivroPorIsbn retorna undefined se não encontrar, e listarLivrosDisponiveis trata a propriedade opcional disponivel com valor padrão. Isso demonstra o uso combinado de tipos de objeto, propriedades opcionais, readonly e type aliases.
Erros comuns
- Modificar o array original: usar
biblioteca.push(livro)em vez de retornar novo array. Isso quebra a imutabilidade e pode causar efeitos colaterais. - Esquecer
readonlyemisbn: se não usar, o ISBN pode ser alterado, contrariando o requisito. - Não tratar
disponivelcomo opcional: se fizerlivro.disponivel === true, livros sem a propriedade não aparecerão na lista. Use?? trueou verifiqueundefined. - Retornar tipo errado em
buscarLivroPorIsbn: se não declararLivro | undefined, o TypeScript pode inferirLivroe causar erro ao retornarundefined.
Outra forma de resolver
Para listarLivrosDisponiveis, poderia usar um loop for com if:
const titulos: string[] = [];
for (const livro of biblioteca) {
if (livro.disponivel !== false) {
titulos.push(livro.titulo);
}
}
return titulos;
É mais verboso, mas pode ser mais legível para iniciantes. A versão com filter e map é mais idiomática em TypeScript.
Saída esperada
{ isbn: '456', titulo: 'Livro B', autor: 'Autor Y', disponivel: false }
[ 'Livro A', 'Livro C' ]