Functional languages typically have type inference.
It’s less that you have to declare something can do IO or throw an exception, and more that you’re calling something from the standard library that does IO or throws an exception.
Most stuff does neither. There’s a type level distinction between normal, regular pure code, and impure effectful code, so it’s easy to tell from the type signature whether a function is pure or not.