Разница в том, что
return $this->invoiceItems->filter(function ($invoice) use ($type) {
/** @var InvoiceItem $invoice */
return $invoice->getType() == $type;
});
Возвращает все элементов, которые соответствуют, или пустую коллекцию ArrayCollection, когда ничего не найдено.
В то время как
foreach ($this->invoiceItems as $invoice) {
if ($invoice->getType() == $type) {
return $invoice;
}
}
return null;
будет только когда-либо возвращать первый элемент массива, который соответствует $invoice->getType() == $type
или нулю, если он вообще не существует.