Boiled down to a sentence: it’s the choice of invoking a method based on whether something has the method, rather than based on whether something is of a certain type.
Use duck typing when you care more about what something can do instead of what something is.
I think duck typing relies a lot on trust. Trust that programmers name things well. If anything has been implemented with a method called .join(), then it better do something join-y, like combining an array into a single string. If it doesn’t, then kaboom, something will break!