In some type systems, you don't need to change it either. Errors will happens only if you've written code that assumes that `target` is a string. If I write a function with the following signature:
fn split(str: string) => string[]
And you called it with
const first_el = split(target)[0]
If you decide `target` to suddenly be an object, then the code you wrote is incorrect, because semantically, `split` only makes sense when the argument is a string. Which is why, even with dynamic typing, you'll see that the documentation of a function will state what kind of parameters it expects.
If you a call chain like `fn1 | fn2 | fn3 | fn4 | split`, Then yeah you need to ensure what reaches `split` is in fact a string. If you're against updating fn[1-4]'s signature, let's say that it's harder to find which function needs to change in a dynamic typing systems.
Dynamic typing is useful for small programs and scripts because they are easy to iterate upon. But for longer programs, I'll take static typing anytime.
Yeah, you are right that ease of drilling down values through the layers is balanced by the need to remember which places actually do something with the value.
While I always liked dynamic languages and probably wrote most of my code in them I don't think they are useful anymore. Tooling got great and LLMs need every chance they get of verifying stuff they hallucinated. At this point I wouldn't mind a language that's strict about typing but other things as well as ownership, protocols, mandatory assertions, tests, code coverage, even some formal verification. As long as I don't have to write them, but LLM does and uses them to check its work, I'm really fond of it.
const first_el = split(target)[0]
If you decide `target` to suddenly be an object, then the code you wrote is incorrect, because semantically, `split` only makes sense when the argument is a string. Which is why, even with dynamic typing, you'll see that the documentation of a function will state what kind of parameters it expects.
If you a call chain like `fn1 | fn2 | fn3 | fn4 | split`, Then yeah you need to ensure what reaches `split` is in fact a string. If you're against updating fn[1-4]'s signature, let's say that it's harder to find which function needs to change in a dynamic typing systems.
Dynamic typing is useful for small programs and scripts because they are easy to iterate upon. But for longer programs, I'll take static typing anytime.