Eliminating any; preferring unknown + narrowing
Replace any with unknown + narrowing; add small guards and assertion functions; toggle strict flags gradually without breaking the build.
Eliminating any; preferring unknown + narrowing is a free TypeScript Academy lesson on CoddyKit — lesson 1 of 2. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 2 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Intro
Goal: Remove any hotspots. Prefer unknown for untrusted values and narrow with simple checks. You will add tiny guards and enable strict flags step by step.
- any → unknown
- typeof/in/instanceof narrowing
- assertion functions
any pitfalls
any turns off safety: wrong shapes or string math slip through compile-time, failing later.
// any hides bugs
function avgBad(values: any): number {
// Compiles even if values is not an array of numbers
return values.reduce((a: number, b: number) => a + b, 0) / values.length
}
// Runtime crash examples:
// avgBad(123)
// avgBad(["1","2"]) // string addition!unknown + narrowing
Use unknown for inputs from the outside. Narrow with Array.isArray and typeof, then compute safely.
// unknown forces checks
function avg(values: unknown): number {
if (!Array.isArray(values)) throw new Error("values must be an array")
const nums = values.filter((v): v is number => typeof v === "number")
if (nums.length === 0) throw new Error("no numbers")
const sum = nums.reduce((a, b) => a + b, 0)
return sum / nums.length
}
// avg([1,2,3]) → 2; avg("oops") throws early with a clear messageType guards
Create a predicate x is T to narrow callers cleanly. Keep guards tiny and focused on structural checks.
// Small predicate to reuse narrowing
export type User = { id: string; name: string }
export function isUser(x: unknown): x is User {
return typeof x === "object" && x !== null
&& typeof (x as any).id === "string"
&& typeof (x as any).name === "string"
}
export function hello(x: unknown) {
if (!isUser(x)) throw new Error("invalid user")
return `Hello, ${x.name}`
}Assertion functions
Assertion functions (asserts x is T) narrow after they run. Use for required preconditions and throw with clear messages.
// Assertion function throws or narrows
function assertUser(x: unknown): asserts x is { id: string; name: string } {
if (typeof x !== "object" || x === null) throw new Error("not an object")
const o = x as Record<string, unknown>
if (typeof o.id !== "string" || typeof o.name !== "string") throw new Error("bad user")
}
export function greetUnsafe(x: unknown) {
assertUser(x) // now x is narrowed after this call
return `Hi ${x.name}`
}Strictness plan
Plan:
- Turn on
noImplicitAnyand fix new errors first. - Introduce guards for external inputs.
- Enable
strictNullChecksand handle undefined explicitly. - Track remaining
anywith ESLint and reduce over time.
unknown vs any check
Quick check: Why prefer unknown over any for untrusted data?
Recap
Recap: Replace any with unknown, add tiny guards or assertions, and raise strict flags in small steps to keep builds green.
Frequently asked questions
Is the “Eliminating any; preferring unknown + narrowing” lesson free?
Yes — the full text of “Eliminating any; preferring unknown + narrowing” is free to read here on the web, and the TypeScript Academy course includes 2 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Eliminating any; preferring unknown + narrowing”?
Replace any with unknown + narrowing; add small guards and assertion functions; toggle strict flags gradually without breaking the build. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 2, so you can start here or from the beginning and move at your own pace.
How long does the “Eliminating any; preferring unknown + narrowing” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Eliminating any; preferring unknown + narrowing
- Enforcing strict flags gradually