First of all, there is not a single approach suitable for all cases where this bad assumption currently resides. Also keep in mind it is not just claims. The only thing each type of entity will have for certain is an ID and a type.
The kind of interface you need really depends on the user. Sometimes you might be fine with just a list of claims or a Fingerprint object. Sometimes you might need that and an EntityId. Perhaps you need more. If the parameter list gets long, or some combination is often repeated and turns out to be a concept in our domain, creating a new aggregate for it is probably a good idea.
There are cases where you inherently get "an entity" and need to handle it, including behaviour specific to the type. At such places it is often good to have dedicated handlers, and these handlers might indeed have some duplication in them. A good example of this is the entity diffing code which I refactored in DataModel 1.0, and for which the EntityDocument interface was introduced.
Note how this object delegates to one of the registered strategies. Such a pattern can be used instead of the often hardcoded handling in Wikibase.git, which prevents addition of new entity types by other extensions. If you look at the individual classes, you will see they are very similar:
There is little duplication though. Just the 3 lines for aliases, labels and descriptions. If that code was more significant, you could create an object to handle it, and use composition. While the rest of the class is still similar, trying to mash this together via inheritance will just lead to increased complexity and loss of flexibility. The wrong abstraction tends to be much more costly then some duplication, and definitely than some similar code.