Skip to content
This repository was archived by the owner on Apr 1, 2022. It is now read-only.

Type Refining

lianghe-houzz edited this page Jul 6, 2017 · 1 revision

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

Clone this wiki locally