Skip to end of metadata
Go to start of metadata

Falseable is a type modifier (indicated by "!" without quotes) which can be used to define that a variable of such a falseable type can hold false in addition to its regular type (it is very similar to the Nullable type modifier but can be used for all types). As an example, a falseable array can hold array and false.

The falseable modifier has to be written to the right of the type as follows

int! $i = false; 
array! $a = [1];
$a = false; 

Please be aware, that these types are treated as separate types and code as the following cause a compiler error:

Would cause a compiler error
int! $a = false;
int $b = $a;

However, one can cast falseable types to the corresponding types:

int! $a = null;
int $b =(int) $a; //or
int $c =() $a;

The falseable and nullable modifier can also be combined whereas the falseable modifier has to be written before the nullable modifier. For instance,

float!? $f = null;
$f = false;
$f = 2.0;
if($f !== null && $f !== false){}


As mentioned, TSPHP treats falseable types as separate types. Nevertheless, for the sake of convenience most operators have been overloaded in order that one can use falseable types almost like their corresponding "normal" type. Following an example:

float! $fF = false;
float $f = 1 + $fF; //overload for float! defined -> no error
string $s = 'concatenation: ' . $fF . $f; //overload for float and float! defined -> no error


Falseable types are especially useful and designed for those users who prefer the return-false-if-something-goes-wrong approach. PHP itself uses this approach for several functions. For instance, strpos returns an int if needle was found in haystack and otherwise false. Consider the following example:

int! $pos = strpos("h","hello");
if($pos !== false){
    int $i = $pos + 1;

If one would not use the falseable modifier, then one would need to write the code as follows:

mixed $pos = strpos("h","hello");
if($pos !== false){
    int $i = (int) $pos + 1;

Which uses mixed and mixed should be avoided when ever possible because it moves type checking to run time. Hence, errors are detected later (run time instead of compile time) and it also has an impact on the performance.

  • No labels