ReactThe five diagnostics, with the fixed version beside each
import { useState } from "react";
const BADGE_TYPE = `type BadgeProps = {
label: string;
count: number;
tone?: "info" | "warn";
};`;
const CASES = [
{
wrong: '<Badge label="items" count="3" />',
right: '<Badge label="items" count={3} />',
error: "TS2322: Type 'string' is not assignable to type 'number'.",
js: "renders 'items: 3' β looks fine until you do arithmetic on it",
},
{
wrong: '<Badge label="items" />',
right: '<Badge label="items" count={0} />',
error: "TS2741: Property 'count' is missing in type '{ label: string; }' but required in type 'BadgeProps'.",
js: "renders 'items: ' with nothing after it",
},
{
wrong: '<Badge label="items" count={n} tone="danger" />',
right: '<Badge label="items" count={n} tone="warn" />',
error: "TS2322: Type '\"danger\"' is not assignable to type '\"info\" | \"warn\" | undefined'.",
js: "sets data-tone='danger', which no stylesheet matches β silently unstyled",
},
{
wrong: '<Badge lable="items" count={n} />',
right: '<Badge label="items" count={n} />',
error: "TS2322: Property 'lable' does not exist on type 'IntrinsicAttributes & BadgeProps'. Did you mean 'label'?",
js: "renders ': 3' β the typo is IGNORED entirely. The worst one.",
},
{
wrong: 'onClick={() => setN("many")}',
right: 'onClick={() => setN(n + 1)}',
error: "TS2345: Argument of type 'string' is not assignable to parameter of type 'SetStateAction<number>'.",
js: "state becomes the string 'many'; the next n + 1 gives 'many1'",
},
];
export default function App() {
const [i, setI] = useState(3);
const c = CASES[i];
return (
<div style={{ padding: 24, fontFamily: "system-ui", lineHeight: 1.6, maxWidth: 620 }}>
<pre style={{ background: "#eef", border: "1px solid #ccd", borderRadius: 8, padding: 10, fontSize: 12 }}>
{BADGE_TYPE}
</pre>
<div style={{ display: "flex", gap: 6, flexWrap: "wrap", margin: "10px 0" }}>
{CASES.map((_, n) => (
<button key={n} onClick={() => setI(n)} style={{ fontWeight: n === i ? "bold" : "normal" }}>
case {n + 1}
</button>
))}
</div>
<div style={{ border: "1px solid #ddd", borderRadius: 8, padding: 12, fontSize: 13 }}>
<div style={{ marginBottom: 8 }}>
<span style={{ color: "#a33" }}>β </span><code>{c.wrong}</code>
</div>
<div style={{ background: "#fdf0f0", border: "1px solid #e0b4b4", borderRadius: 6, padding: 8,
fontSize: 12, fontFamily: "ui-monospace, monospace", marginBottom: 8 }}>
{c.error}
</div>
<div style={{ marginBottom: 8, color: "#666", fontSize: 12 }}>
<strong>without types:</strong> {c.js}
</div>
<div>
<span style={{ color: "#161" }}>β
</span><code>{c.right}</code>
</div>
</div>
<p style={{ fontSize: 13, color: "#666" }}>
Case 4 is the one to remember. An unknown prop in JSX is not an error β
it is simply dropped, so the component renders with a missing label and
nothing anywhere tells you. Every diagnostic above was produced by
actually compiling this component with the wrong usage.
</p>
</div>
);
}