← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Type Inference

compiler PHP 7.0+ Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and psalm as the tools — these are specialist static analysers, not default linters. The code pattern flagged is redundant or incorrect @var annotations that conflict with what the analyser would infer, and the automated field is yes but only via these specialist tools.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is to annotate function/method signatures and let the analyser infer inside the body — this is a small, localised change per function boundary rather than a one-liner swap, but also doesn't span multiple files. Common mistakes like over-annotating or missing boundary annotations are corrected function by function.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The applies_to covers web and cli PHP contexts broadly, but the burden is mainly felt at function/method boundaries where explicit annotations are needed. The rest of the codebase benefits from inference inside bodies without ongoing cost; the tax is paid at the interface layer rather than pervasively.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly states that developers confuse type inference with dynamic typing — a fundamental misunderstanding that contradicts how static typing works in other contexts. Additionally, common mistakes show developers assume wide types when inference is narrow, and assume inference works across function boundaries in PHP when it does not. These contradictions with intuitions from dynamically typed PHP or other languages make this a serious cognitive trap.

About DEBT scoring →

Also Known As

type deduction implicit typing inferred types Hindley-Milner

TL;DR

The compiler's ability to automatically deduce the type of an expression without an explicit annotation, based on context and assigned values.

Explanation

Type inference lets developers write less verbose code while retaining type safety. The compiler analyses assignments, function return values, and usage context to infer types. Hindley-Milner is the classic algorithm (used in Haskell, ML, Rust) and can infer types globally across an entire program. PHP's type system requires explicit declarations for parameters and return types but infers types in several contexts: `$x = 5` gives `$x` an inferred int type in static analysers (PHPStan, Psalm), and `match` expressions can have their return type inferred. TypeScript uses local type inference heavily — `const x = 42` infers `number`, array literals infer their element type, and generics are inferred from call-site arguments. Understanding how inference works helps you write cleaner code and understand why a type error fires even without explicit annotations.

Common Misconception

Type inference means dynamic typing — it does not. Inferred types are still fully static and checked at compile time; the compiler simply deduces them rather than requiring you to write them explicitly. The code is just as type-safe.

Why It Matters

Inference reduces annotation boilerplate while preserving safety. It also directly affects how PHPStan and Psalm analyse your code — variables without explicit annotations still get inferred types, and those types drive error detection throughout the analysis.

Common Mistakes

  • Assuming a variable has a wide type when the inferred type is narrow — assigning `$x = []` then later using it as `array<int>` may fail static analysis if elements of wrong type are pushed.
  • Over-annotating in TypeScript where inference is already precise — `const x: number = 42` is redundant noise.
  • Relying on inference across function boundaries in PHP — PHPStan infers local variables but cannot infer parameter types of public methods without annotations.
  • Assuming inference works across all PHP versions — static analysers vary in inference depth; PHPStan level 9 infers more aggressively than level 0.

Code Examples

💡 Note
In PHP, inference inside function bodies is strong — annotating the signature is enough for PHPStan to track narrowed types through control flow.
✗ Vulnerable
// TypeScript: fighting inference with redundant annotations
const items: Array<string> = ['a', 'b', 'c']; // redundant — inferred already
const doubled: Array<number> = items.map((s: string): number => s.length); // over-annotated

// PHP: not trusting analyser inference, adding wrong doc comment
/** @var string $result */  // WRONG — actual type is int|false
$result = strpos($haystack, $needle);
✓ Fixed
// TypeScript: let inference do the work
const items = ['a', 'b', 'c'];            // inferred: string[]
const lengths = items.map(s => s.length); // inferred: number[]

// PHP: annotate function signatures, trust inference inside
function getPosition(string $haystack, string $needle): int|false {
    $pos = strpos($haystack, $needle); // inferred int|false by PHPStan
    if ($pos === false) return false;
    return $pos; // narrowed to int here
}

Added 24 Mar 2026
Views 26
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Perplexity 8 Amazonbot 7 Unknown AI 3 Google 2 Ahrefs 2 ChatGPT 1
crawler 22 crawler_json 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Annotate function and method signatures — let static analysers infer types inside the body rather than adding redundant inline annotations
📦 Applies To
PHP 7.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
/** @var */ annotations on local variables that override or duplicate what the analyser would infer correctly
Auto-detectable: ✓ Yes phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function

✓ schema.org compliant