TypeScript vs PHP Type System
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list TypeScript compiler and ESLint as tools. The TypeScript compiler will flag type mismatches when a PHP developer misuses `any` or omits proper interface usage, but the subtler structural-vs-nominal confusion won't always produce a compiler error — it requires ESLint rules or careful type-checking review to surface the conceptual misuse pattern.
Closest to 'simple parameterised fix' (e3). The quick_fix describes mapping TypeScript interfaces to PHP class contracts, generics to PHP templates, and union types to PHP unions — this is a pattern-level replacement (updating annotations and interface usage) within one component or file at a time, not a one-line swap but not a cross-cutting refactor either.
Closest to 'localised tax' (b3). The applies_to scope covers web and cli contexts broadly, but the burden is primarily cognitive onboarding cost for PHP developers rather than a structural weight on the entire codebase. Once a developer understands structural typing, the tax is lifted and the rest of the codebase is largely unaffected.
Closest to 'serious trap' (t7). The misconception field explicitly states that TypeScript and PHP types 'work the same way,' but structural typing (shape-based) directly contradicts nominal typing (declaration-based) familiar to PHP developers. This contradicts how an analogous concept works in another widely-used language (PHP), making it a serious trap that competent PHP developers will consistently fall into without explicit instruction.
Also Known As
TL;DR
Explanation
TypeScript: structural typing (does this object have the right shape?), type inference (types inferred without annotations), union types, conditional types, mapped types, template literal types. Types erased at compile time — zero runtime cost. PHP: nominal typing (is this the declared class/interface? — must explicitly implement), gradual types, union types (PHP 8.0), intersection types (PHP 8.1), runtime enforcement with strict_types. Key difference: TS structural duck typing vs PHP explicit interface declaration.
Common Misconception
Why It Matters
Common Mistakes
- Expecting PHP-style nominal interface checks in TypeScript — structural typing is different
- Over-annotating every variable — TypeScript's inference is powerful, let it work
- Forgetting TypeScript types are erased at runtime — use typeof/instanceof for runtime checks
- PHP generics via @template vs TypeScript native generics — TS generics are more expressive
Code Examples
// PHP habit: over-annotating in TypeScript:
const name: string = 'Alice'; // Unnecessary — TypeScript infers: string
const user: object = { id: 1 }; // Too broad — loses the specific shape
// Expecting nominal interface check:
interface Printable { print(): void; }
// PHP expectation: class must explicitly 'implements Printable'
// TypeScript reality: any class with print() method satisfies it
// TypeScript — idiomatic with inference:
const name = 'Alice'; // TypeScript infers: string
const user = { id: 1, email: 'alice@example.com' }; // Infers shape
// Structural typing — shape compatibility:
interface Printable { print(): void; }
function printIt(p: Printable): void { p.print(); }
class Document { print() { console.log(this.toString()); } }
printIt(new Document()); // Works — Document has print(), structurally compatible
// No 'implements Printable' needed in TypeScript