Выбор ответа 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 по сигнатурам: аргумент должен целиком подойти под одну из них.

Варианты ответа

  1. Сигнатура реализации видна снаружи и конфликтует с перегрузками
  2. Массивы нельзя передавать в перегруженные функции, только примитивы
  3. Аргумент сверяют с каждой перегрузкой по отдельности, и union не подходит ни к однойправильный ответ
  4. Нужно включить strictBindCallApply, чтобы перегрузки проверялись по union

Разбор

Разрешение перегрузок не «раскладывает» union по сигнатурам: аргумент должен целиком подойти под одну из них. Сигнатура реализации снаружи как раз не видна, поэтому вызвать функцию с union нельзя. Рекомендация из handbook: если перегрузки отличаются только типом параметра, предпочитайте одну сигнатуру с объединением. strictBindCallApply касается call/apply/bind, массивы в перегрузках разрешены.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме