You can overcome drawbacks of structural typing in TypeScript by creating nominal types with a little bit of extra code.
If the type is shaped like a duck, it is a duck. If a goose has all the same attributes as a duck, then it also is a duck.
This feature gives you the flexibility to return and preserve the identity of any type, related but different from protocols and generics.