This is happening because the kind of find
is always the union of type of array elements and undefined
.
So, for example, if you have an array of the type Array<number>
and invoke find
, the type of return will be number | undefined
. And this union (with undefined
) is indeed necessary, since, as stated in language specification, Array.prototype.find
should return undefined
if the element you are looking for does not exist within the array - which, let’s face it, is a completely plausible scenario of happening.
Learn more about type unions in Typescript.
So you have some options...
Set the function return to possibly undefined
For this, just make the type of return as a union of the desired type and undefined
.
In your case, the type of return should be Tarefa | undefined
. Thus:
function buscarPorId(id: number): Tarefa | undefined {
const tarefas: Tarefa [] = this.listarTodos();
return tarefas.find(tarefa => tarefa.id === id);
}
Return a value fallback of the desired type in case the search fails
In this case you can create an instance of Tarefa
fallback if the search was not successful. Something like this:
function buscarPorId(id: number): Tarefa {
const tarefas: Tarefa [] = this.listarTodos();
const encontrada = tarefas.find(tarefa => tarefa.id === id);
// Caso não tenha sido encontrada...
if (!encontrada) {
return new Tarefa(...); // Informações de fallback
}
return encontrada;
}
But in this case this doesn’t seem like a very alternative clever, since it would be "creating" a task which the user did not explicitly create. But it is a valid possibility in other cases and that’s why I put it here.
Make an exception
You can make an exception if no item has been found. It may seem a little absurd (in this case it is, but in some others it may make more sense). Just remember that the caller should be aware of the possible launch to not break the application.
Thus:
function buscarPorId(id: number): Tarefa {
const tarefas: Tarefa [] = this.listarTodos();
const encontrada = tarefas.find(tarefa => tarefa.id === id);
// Caso não tenha sido encontrada...
if (!encontrada) {
throw new Error('Nenhuma tarefa foi encontrada com esse parâmetro de busca.');
}
return encontrada;
}
For more details on exceptions in general, read this excellent response.
Completion
In short, I think it’s worth returning undefined
(the first alternative I presented), since Typescript will compel the caller to deal with the possible value undefined
, just as we were forced to deal with the possible undefined
returned by Array.prototype.find
.
Remember that the option strictNullChecks
shall be empowered to ensure that security related to null
or undefined
be guaranteed. Interestingly, the example of the find
is used to explain this option in such documentation.