-
Notifications
You must be signed in to change notification settings - Fork 1
Type Refining
Type refining means the ability to "narrow down" the type for a particular code branch. See the example below:
<?php
/**
* @param string|null $nullableStr
*/
function foo($nullableStr) {
$x = $nullableStr . "str"; // error, because $nullableStr can be null
if ($nullableStr === null) {
echo "You passed null";
} else {
$x = "You passed " . $nullableStr; // no error, Tap knows $nullableStr in not null here
echo $x;
}
$y = $nullableStr . "str"; // error, because $nullableStr can be null
}
Besides === null and !== null checking, Tap can also understand internal checking functions like is_string(), is_array(), etc.
Please note that you need to explicitly check if ($x === null) {} instead of if ($x) {}. Because Tap requires the condition inside if to be bool type, while $x is not.
Type refiner will not work if your if is too complicated, for example, if we replace the if in above code with if (false || $nullableStr) {...}, though it's obviously equivalent to human being, Tap can't do any refine. Because theoretically it is no easy than 3-SAT problem, which is NP-Complete, Tap will not try to find a general solution, just heuristically checking the most frequent patterns like single clause in if.
To see what type refiner can do, see the test file: https://github.com/Houzz/tap/blob/master/test/test_files/refine.php