rector/type-perfect
Type Perfect adds 10 PHPStan rules to tighten type declarations: replace empty/isset checks with instanceof for precise narrowing, prefer explicit getters over magic array access, and enforce interface signatures. Easy to enable even on legacy code; improves reliability fast.
Start by installing the package and loading the extension. Run:
composer require rector/type-perfect --dev
Then ensure PHPStan loads the extension—either via phpstan/extension-installer (recommended) or manually include vendor/rector/type-perfect/config/extension.neon in your phpstan.neon. Next, run PHPStan on your codebase (even if it fails level 0). Begin with the three rules enabled by default: explicit instanceof checks, no magic array access, and interface compliance. These surface immediate, low-effort wins like:
// Before: implicit type ambiguity
if (! $this->item) { return; }
// After: explicit type guarantee
if (! $this->item instanceof Item) { return; }
null_over_false → no_mixed_property → no_mixed_caller → narrow_param → narrow_return.null_over_false to refactor Eloquent scopes like whereActive() that return false instead of null.no_mixed_property on model relations (e.g., public $relation) to force typed Relation or BelongsTo hints.rector/rector to auto-fix narrow_param and narrow_return violations.1 → warning) until your codebase stabilizes. Use ignoreErrors for vendor files early on.private $foo) cause PHPStan to skip all analysis on their usage—including typos. no_mixed_property catches these silently broken flows early.__get() and __call() may trigger false positives with no_mixed_caller. Exclude dynamic relations via ignoreErrors or add docblocks (@method) for known relationships.create(): Model, verify all callers receive the exact subtype. If a factory truly returns unions (ConferenceTalk|MeetupTalk), prefer union return types (: Talk|ConferenceTalk|MeetupTalk) over forced specific types.parameters.type_perfect.*, not in includes or extends. Conflicts with other PHPStan sets (e.g., laravel set) arise when duplicated keys exist—always validate with vendor/bin/phpstan --debug.null_over_false first: It’s the safest—fixing false → null improves semantics without changing logic. Laravel’s convention (find()?, first()?) makes this especially effective.How can I help you explore Laravel packages today?