I think dependent types is supposed to solve this problem (for example, rather than just a list of ints, it can encode that it's currently a sorted list of ints) but they don't seem practical to use at the moment.
But it's a test suite that can be much cheaper to write and maintain.
the converse doesn't hold. You can write new code that will benefit from the guarantees of existing types. But you'd have to write new tests if you didn't have types.
The tests/types correspondence still holds: if you write new code, you will often also need to alter the types to correctly describe the changed domain. In the username example above, after adding username validation it would be a good idea to have a dedicated `Username` type that can only contain valid usernames instead of just stuffing everything into `String`. If you count extra time writing and refactoring tests after adding new code, you should also count the extra time writing and refactoring additional types after adding new code.
Seriously though, these two concepts have some overlap that should be explored more.