Зачем нужны DTO, когда есть типы и интерфейсы в языках программирования?
DTO нужны, для того что бы ограничить и структурировать взаимодействия разных слоев и сущностей программы. Этот принцип относиться ко всем языкам программирования, а не к конкретному. Тут понятно.
Но возьмем к примеру фреймворк - Nest. Там использование DTO в виде классов, аргументируется тем, что TypeScript при транспиляции "теряет" эти типы и поэтому их реализовывают сразу в виде классов JS.
Но если взять тот же C# или Java. Там тоже применяется DTO, но зачем, если можно использовать интерфейсы самого языка?
DTO объекты часто пересекают границы Языков (Java/JavaScript/GWT) и сетевых протоколов (Rest/Graphql/SOAP/Avro).
И эти объекты могут нести на себе семантику только чистых данных. Вы не сможете через сеть
из Java в C# например передать интерфейс или объект с методами.
И многие фреймворки искусственно ограничивают DTO как раз для того чтобы эти объекты однозначно
декодировались всеми сторонами-участниками протокола взаимодействия. А фреймворки - обычно
предоставляют средства кросс-компилляции этих DTO.
Потому что компоненты приложения не должны иметь жёстких связей между собой и должны опираться на максимально узкий скоуп используемых данных. Незачем какому-нибудь там адаптеру, шлющему в очередь уведомления об изменения статуса модели, иметь доступ ко всем полям этой модели и иметь зависимость от прикладного ядра или слоя доступа к данным.