Good... so rather than googling myself to death trying to come up with the correct term.
I believe it's because of the IF/THEN that we see this.
SQL Processes both branches of the IF/THEN statement during parsing/etc and then during execution it determines which plan to use. I'm totally guessing here, but it would appear that variable declarations are considered part of the if/then block not a result of execution of it. So the IF/THEN is actually part of the creation of the variable, and such, when the IF/THEN finishes we have the variable.
It would explain why this generates an error, essentially the DECLARE statements are part of the IF/THEN block and the declares become available after it completes.
DECLARE @i INT = 1
IF @i = 2
DECLARE @j INT = 3
DECLARE @j FLOAT = 3.1415
Msg 134, Level 15, State 1, Line 7
The variable name '@j' has already been declared. Variable names must be unique within a query batch or stored procedure.
This seems to happen because until the runtime engine gets to the IF comparison, both paths are considered valid, and when it finishes those resources become available?
In reality this is a big shrug for me, it's one of those things I've seen happen for years... and it's confused developers and just caused me to just ask them to declare all the variables they need at the beginning of their stored procs.