Duck typing isn't a bad thing. In fact, it's great. You just need to annotate the ducks instead of the types. For a great example of how to do it, look at Haskell's type classes.
(In fact, Haskell's easyness of integrating generic code is visible even to a beginner, but I never notice that this is because the entire language is based on duck typing.)