strong-types

Installation
SKILL.md

strong-types

Every value should have one knowable type at every point. If the author cannot say what an expression's type is without running the code, the code is not done. Keep it proportional: for a small edit, check silently and mention only decisions that change the implementation. Use the project's existing checker (tsc, PHPStan, Psalm, mypy, pyright, compiler flags) at its configured level; match or exceed it, run it the supported way, and report pre-existing failures or an unavailable checker rather than weakening settings. Preserve framework or interface type contracts exactly; contain and justify a required escape hatch instead of narrowing a signature incompatibly. Pair with maintainable-code when available.

The core move

$image = $location->preview ?? $location->banner ?? $location->thumbnail;

This leaves four questions open: each property's type, which are nullable and why, the type of $image, and whether the whole chain can still be null. Move the chain into one named, typed owner with an explicit all-null policy, and use that at every call site:

public function primaryImage(): Image
{
    return $this->preview ?? $this->banner ?? $this->thumbnail
        ?? throw new MissingImageException($this->id);
}
Installs
50
GitHub Stars
57
First Seen
Jul 6, 2026