There's a very simple rebuttal. Have this function:
function greetPerson(name) { ... }
Call it in a bunch of places like this:
greetPerson(user.name)
Now change the signature:
function greetPerson(userId) { ... }
What code do you need to update to fix the breakage you now caused?
A dynamically typed language can't tell you without some serious static analysis, which to my knowledge doesn't exist. TypeScript can know this both when linting in your editor, and at compile time. Old signature:
function greetPerson(name: string)
New signature:
function greetPerson(userId: number)
Just write tests, some might say. But you've got your test right there: The type is the test for this particular problem. Unit tests should test behaviour, not types. (Since unit tests should cover failure cases, duck-typed languages arguably require that you test calling your functions with a wide variety of bad inputs.)
In practice, large programs will never have enough, or good enough, tests, because they have to be written separately from the code they're testing. Type systems allow us to describe our rules in the code.
Note that there are statically typed languages (OCaml and F# being notable examples) where the type inference is sufficiently good that you rarely need to write out the types of signatures, let alone variables or return values:
let greetPerson name = ...
greetPerson user.name
The fact that they can do this invalidates the usual "static typing require lots of unnecessary verbosity" argument, because it's not true.