By name, type, and structure. In typescript for example:

   let full_name = (in: { first: string, last: string }) => in.first + " " + in.last
Then you can use this function on any data type that satisfies that signature, regardless of if it's User, Dog, Manager etc.

This is very much backwards from most programming practices. It's much more common to have an operation that makes sense for many structurally different types, such as add(a, b) where a and b could be integers, floating point numbers, complex numbers, 3D vectors, 4D vectors, matrices etc.

Most programming happens in nominally typed languages where the above isn't trivially possible. To be fair that example is contrived, but you can imagine operations happening on large dicts where only a small subset of the fields are necessary.

This is actually a relatively common example of the benefits of either polymorphism (for the a.add(b) version) or generic methods/templates. You'll actually find libraries that have a method or template function like this in C++, Java, C#, and other commonly used static languages.