I think it first perform all the required substitutions and then parses the command. This gives you the possibility to define entire condition in a variable. Then are the arguments checked and it blows up.
The if command was written very early in CMake’s history, predating the ${} variable evaluation syntax, and for convenience evaluates variables named by its arguments as shown in the above signatures. Note that normal variable evaluation with ${} applies before the if command even receives the arguments.