Strict Mode and Eliminating any
Enable all strict flags in tsconfig, use unknown instead of any, apply type assertions safely, and migrate a weakly-typed file to strict.
Strict Mode and Eliminating any is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. 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 Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Strict Mode?
strict: true in tsconfig.json turns on every TypeScript safety flag — the bar for serious projects. It catches null bugs, untyped parameters, and unsafe assignments at compile time.
What strict Enables
strict is a meta-flag that turns on: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, alwaysStrict, noImplicitThis, useUnknownInCatchVariables.
strictNullChecks
Without it, null and undefined are assignable to every type — a constant source of bugs. With it, you must handle null cases explicitly.
// Without strictNullChecks — runtime error:
function greet(name: string) { return name.toUpperCase(); }
greet(null); // compiler allows, crashes at runtime
// With strictNullChecks:
function greet(name: string | null) {
if (name == null) return '';
return name.toUpperCase();
}noImplicitAny
Parameters without a type annotation default to any without this flag — silently bypassing the type system. With noImplicitAny, you must annotate them.
// Without noImplicitAny:
function format(value) { return value.toUpperCase(); } // value: any
// With:
function format(value: string) { return value.toUpperCase(); }strictPropertyInitialization
Class properties without a definite initializer become possibly undefined. Either initialize them or use the definite assignment operator !.
class User {
name!: string; // tell TS: I'll set this elsewhere
age = 0; // default initialiser
email: string; // ERROR with strictPropertyInitialization
constructor(email: string) { this.email = email; } // FIX: init in ctor
}Use unknown Instead of any
any opts out of type checking. unknown is type-safe — you must narrow it before use. Always prefer unknown.
// any — no checks, bug magnet:
function parse(input: any) {
return input.toUpperCase(); // compiler is fine, runtime may crash
}
// unknown — must narrow:
function parse(input: unknown) {
if (typeof input === 'string') {
return input.toUpperCase();
}
throw new Error('Expected string');
}Type Assertions Safely
If you must assert (you know better than TS), prefer the as syntax. Don't double-assert (x as unknown as T) unless you genuinely have no choice — it's a code smell.
const el = document.getElementById('app') as HTMLDivElement;
el.style.background = 'blue';
// Safer alternative: runtime check
const el = document.getElementById('app');
if (!(el instanceof HTMLDivElement)) throw new Error('app missing');
el.style.background = 'blue'; // narrowed to HTMLDivElementEliminating any from a Project
Strategy: enable strict, fix the resulting errors one file at a time. Use unknown + narrowing. Add @ts-expect-error with a TODO comment for known-bad spots so they can't be ignored.
Lint Rule: no-explicit-any
Add @typescript-eslint/no-explicit-any to your ESLint config to block new any from being added.
// .eslintrc.json
{
"rules": {
"@typescript-eslint/no-explicit-any": "error"
}
}strictFunctionTypes
Enforces contravariant function parameter checking — prevents assigning functions with broader parameter types than expected, which would crash at runtime.
Catch Variable Type
useUnknownInCatchVariables makes catch (e) infer e: unknown instead of any. You must narrow before accessing properties.
try {
doRisky();
} catch (e) {
// e is unknown
if (e instanceof Error) {
console.error(e.message);
} else {
console.error('Unknown error', e);
}
}Migration Tips
Enable strict on new projects from day one. For legacy: enable flags incrementally. Start with strictNullChecks (biggest win), then noImplicitAny. Use //@ts-expect-error rather than //@ts-ignore so the comment is removed when the issue is fixed.
Quick Check
Why is unknown safer than any when you don't know the type of a value?
Recap: Strict Mode
Enable strict: true for full safety. strictNullChecks forces null handling. noImplicitAny requires parameter annotations. strictPropertyInitialization for class fields. Use unknown instead of any — narrow with type guards. Avoid double assertions. Lint with no-explicit-any. Migrate legacy code one file at a time using @ts-expect-error markers.
Frequently asked questions
Is the “Strict Mode and Eliminating any” lesson free?
Yes — the full text of “Strict Mode and Eliminating any” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “Strict Mode and Eliminating any”?
Enable all strict flags in tsconfig, use unknown instead of any, apply type assertions safely, and migrate a weakly-typed file to strict. You practise Frontend 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 Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Strict Mode and Eliminating any” 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 Frontend Academy lesson?
Yes. Every Frontend 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
- Template Literal Types
- Decorators and Metadata
- TypeScript with React: FC generics hooks
- Strict Mode and Eliminating any