The following discussion ignores the existence of _MEM and PEEK/POKE because they're hacky and break the type system.Theoretically speaking, QB64 is a statically typed language. The compiler needs to be able to determine the type of every variable, parameter, operator and constant at compile-time.
Of course if the compiler can work it out the human is supposed to be able to do so as well, but as mentioned you could potentially get confused if there's lots of variables.
Because all types are resolved at compile-time, the final program doesn't have any explicit knowledge of a variable's type (there's no table of variables and their types in the final binary), though of course where appropriate it knows to operate on two bytes or four bytes or whatever.
But that doesn't mean we couldn't include that information - recall the LEN function returns the size of a variable, that's evaluated at compile-time and just replaced with a simple integer constant in the binary. We could add a new function _TYPEOF(x) which is compile-time evaluated to a number that represents the type. For example, _TYPEOF(X%) = 1, _TYPEOF(Y&) = 2.
This gives meaning to a conditional like
IF type(variable_defined) = INTEGER then variable_defined = val(variable$ ()) ELSE
If we just interpret INTEGER as the value 1 (if we were being properly formal we'd add a new variable type to the language that holds types, but that's a bit of overkill for this).
Practically speaking this would probably work fine for numeric types, but poses problems if, say, strings are involved:
if _typeof(x) = string then
x = "hello"
else
x = 2
end if
Now you'll always get a compilation error because no matter the type of x one of the branches will have a type mismatch. Although only one branch will ever be executed, the compiler still wants to compile both.
This specific case could be solved by making this a pre-compiler ($IF) feature instead, and that's probably a better option for the situation posed in this thread. But if we persist with this idea a little more we can come up with something (I think) rather interesting:
T = typeof(x%)
If rnd > 0.5 then T = typeof(y&)
If T = INTEGER then print 1 else print 2
in this program we could never use a pre-compiler because the value of T is unknown until runtime (RND is really a stand-in for and kind of input or complex state).
Note that _mem gives you some of this: in some cases you can ask it what the type of the variable being wrapped is. But you can also go ahead and just treat an integer as a string, which utterly breaks any kind of formal type system.
Written on a phone at quarter to 3 in the morning, sorry for the inevitable typos.