Выбор ответа Senior Дженерики обновлено
Перегрузки и аргумент-объединение
Вопрос
Почему последняя строка не компилируется?
function len(s: string): number;
function len(arr: unknown[]): number;
function len(x: string | unknown[]) { return x.length; }
declare const v: string | number[];
len(v);
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Аргумент сверяют с каждой перегрузкой по отдельности, и union не подходит ни к одной. Разрешение перегрузок не «раскладывает» union по сигнатурам: аргумент должен целиком подойти под одну из них.
Варианты ответа
- Сигнатура реализации видна снаружи и конфликтует с перегрузками
- Массивы нельзя передавать в перегруженные функции, только примитивы
- Аргумент сверяют с каждой перегрузкой по отдельности, и union не подходит ни к однойправильный ответ
- Нужно включить
strictBindCallApply, чтобы перегрузки проверялись по union
Разбор
Разрешение перегрузок не «раскладывает» union по сигнатурам: аргумент должен целиком подойти под одну из них. Сигнатура реализации снаружи как раз не видна, поэтому вызвать функцию с union нельзя. Рекомендация из handbook: если перегрузки отличаются только типом параметра, предпочитайте одну сигнатуру с объединением. strictBindCallApply касается call/apply/bind, массивы в перегрузках разрешены.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.