> В этом коде почему-то работает только return "No such contact" и return "No such property".
Посмотрите внимательно чужие решения. Они сводятся к тому, чтобы сначала найти контакт по имени в цикле, и только если найден контакт, тогда уже смотреть в нем свойства. А за пределами цикла, если не найден контакт, тогда уже только возвращать конечное решение "Контакт не найден". Вы же делаете иначе - вы сразу смотрите тот это контакт или нет, и если не тот, то возвращаете ошибку. В итоге ваша логика может сработать только если первый контакт в массиве соответствует запрошенному и свойство запрошено корректно. В противном случае вы возвращаете ошибку и далее перебор в цикле уже не выполняется.

По второй части вопроса: советую уже сейчас вам начинать изучать TypeScript, вы тогда начнете быть более внимательным к типам. В целом вы идею правильно поняли с поиском по внутренним массивам, но нельзя сравнивать строку с массивом. Для примера ваше: item.likes == name.

item.likes здесь - массив, например ["Pizza", "Coding", "Brownie Points"], и вы его пытаетесь сравнить со строчным name. Нельзя так. Почти всегда будет ложь, ито, только потому что вы используете нестрогое сравнение ==. Если бы использовали строгое ===, то 100% было бы всегда ложь, потому что типы не совпадают.
В вашем случае, если бы вы хотели найти по элементу во вложенном массиве, то надо еще внутри искать по массиву, а не просто через сравнение. Пример.

var contact = contacts.find(item => item.likes.includes(name));

Только здесь надо понимать, что name здесь - не имя контакта, а именно элемент массива likes, то есть "Pizza", "Coding" или "Brownie Points".

Описание метода Array.includes смотрите здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes