Именно. Второй является одновременно датой и кодатой. В ТС как раз с этим и проблемы: если на этапе компиляции не вычислить true/false у карри аргумента - то тип будет юнион - всё равно что без кондишена прописать тип результата юнионом (если не хакать перегрузками)
не всегда, не копал твой код, да все классы но есть implements для подвязки множества интерфейсов есть with для множества примесей И через них тоже можно определять и реализовывать type-safety. С примесями есть подводные камни, с интерфейсами не напарывался.