Видеоуроки, интерактивный редактор и сохранение прогресса — бесплатно, сразу после входа.
ВойтиСоздать аккаунт — бесплатноЗакончили урок?
Войдите, чтобы отмечать прогресс
{ ...state } создаёт новый объект, и TypeScript считает его типом T: все поля скопированы из значения типа T. Дальше next.count = 0 разрешено, потому что ограничение гарантирует числовое поле count. Исходный объект при этом не меняется.
Этот вариант тоже верный. Спред дженерик-значения TypeScript типизирует как пересечение T & { count: number }, а пересечение с T всегда подходит под T. Разница только в стиле: в одну строку короче, через переменную нагляднее видно, что сначала копируем, потом меняем.
Ключевое в обоих вариантах одно: в результате есть ...state. Без него поля, которых функция не знает, теряются.
Если функция обещает вернуть T, единственный честный источник значения типа T это аргументы. Создать его с нуля нельзя, потому что функция не знает, какие поля ещё есть у T. Соблазн «починить» это через return { count: 0 } as T стоит гнать: компиляция пройдёт, а cleared.label окажется undefined, ровно та ошибка, от которой предупреждал компилятор.