Static type systems don't necessarily prevent accidental null value usage.The better ones do.
Some languages with static type systems, notably C and its descendants, have reference or pointer types that are nullable by default. With the wisdom of hindsight, that design decision is regrettable; Tony Hoare himself famously called inventing null references his “billion-dollar mistake”.
There are safer alternatives. For example, you can have a type that makes optionality explicit, so it contains either nothing or a single value of some known type. Before you can work on the contained value, if there is one, you must deliberately extract it; the type system will prevent you from accidentally using the optional value in place of the contained value. In Haskell, this type is called Maybe a. Rust has Option. In OCaml, it’s 'a option.
All of the "decent static type" systems I'm aware of have the same issue with undefined values that break behavior. E.g. zero's as integers, empty strings.
Again, with a sufficiently expressive type system, you can encode properties such as a list being non-empty in your types. This lets you prevent illogical actions like trying to take the head of a list with nothing in it. You sometimes see these techniques if you’re working on high reliability systems with formal verification.
You can also handle edge cases safely by replacing a partial function that is undefined for certain inputs, such as dividing by zero or taking the head of an empty list, with a total function that gives you back an optional value as described above.