New in Rector 0.15: Complete Safe and Known Type Declarations

This feature is available since Rector 0.15.0.

Rector is helping with PHP upgrades and framework migrations. It also helps to rise the type coverage of your project.

Rector completes the type declarations for parameters, returns, and properties, with one Rector rule per each case. The only problem was, these rules use PHPStan type inference that relies on docblocks, and it could complete strict types that are not true. You burn once, and then you ignore these rules forever.

We want you to Feel 100 % Safe

Our goal is to make Rector reliable, so it does not guess and does not require your attention on every change. Instead, it must work without flaws and be 100 % reliable.

That's why we slowly refactored away from these rules, split them into dozens of small ones that work only with strictly known types.



Known and Safe Types First Only

Before, Rector would make this change:

 class Project
 {
-    private $name;
+    private string $name;

     /**
      * @param string $name
      */
     public function __construct($name)
     {
         $this->name = $name;
     }
}


Then we create the Project based on the API call:

$projectName = $this->apiCaller->getProjectName(123);
$project = new Project($projectName);

and get a crash as pass a null to the Project constructor. We don't want that.

From Rector 0.15, we removed the ParamTypeDeclarationRector, ReturnTypeDeclarationRector, and PropertyTypeDeclarationRector and their array alternatives, so this will not happen.


Now, Rector takes into account only strict type declarations:

 class Project
 {
-    private $name;
+    private string $name;

     public function __construct(string $name)
     {
         $this->name = $name;
     }
}

or

 class Project
 {
-    public function getSize()
+    public function getSize(): int
     {
        return strlen($this->name);
     }
}

How to Upgrade to Rector 0.15?

We removed the TYPE_DECLARATION_STRICT set and moved reliable rules to the TYPE_DECLARATION set. Now you can use a single set to handle the type declarations.

 use Rector\Config\RectorConfig;
 use Rector\Set\ValueObject\SetList;

 return static function (RectorConfig $rectorConfig): void {
     $rectorConfig->sets([
         SetList::TYPE_DECLARATION,
-        SetList::TYPE_DECLARATION_STRICT,
    ]);
 };


Protip: One by one

Take a single rule from the TYPE_DECLARATION set, one by one. Apply the rules slowly on your code base and create a pull request per rule. Soon the strict type declarations will be everywhere they can.

Start with return type declaration rules first. They're the easiest to apply and tolerated thanks to return type covariance.