Constraint (<T extends U>) — нижняя граница capability: ограничивает, что можно передать, и открывает члены U в body. Default (<T = D>) — другое: fallback для T, когда inference ничего не нашёл. Одно сужает дверь; другое заполняет blank.
Unconstrained <T> maximally permissive, но бесполезен внутри: T может быть чем угодно, свойство не прочитать. Constraint чинит: <T extends { length: number }> — promise, что у каждого T есть .length, body может его трогать. Type-level «принимаю всё, что quacks like this» — structural, не class hierarchy.
Default в другом измерении. <T = string> ничего не говорит о allowed; говорит, чем T становится, когда compiler не вывел из arguments. Можно оба: <T extends { length: number } = string[]> — constrained and defaulted.
Итог
Constraint = минимальная capability + доступ в body; default = fallback inference; разные оси.