Stop Using any: Replace It in 10 Minutes
Find every any, then replace each one with a named type, a function type or unknown with a check. After this, a typo like prise is a compile error instead of NaN.
Every any in your code is a spot where the compiler stopped checking. This is a 10-minute pass to find them and replace each one with something real. You do not need a fancy tool. You need to sort each any into one of four cases.
Step 1: find them
Search your source folder for any. In an editor, use search across files for : any and <any> and as any. In a terminal on macOS or Linux:
grep -rn ": any" src
On Windows PowerShell:
Select-String -Path src\*.ts -Pattern ": any"
Write the count down. You will want to see it go down.
Step 2: see what an any hides
Here is a function typed with any. It compiles with no errors.
function total(items: any): any {
let sum = 0;
for (const item of items) {
sum += item.qty * item.price;
}
return sum;
}
console.log(total([{ qty: 2, prise: 50 }]));
NaN
The call has a typo, prise, and the answer is NaN. Nothing in the code looks wrong. The compiler could not help, because you told it not to look.
Case 1: an object you control
Give the shape a name and use it.
type Line = { qty: number; price: number };
function total(items: Line[]): number {
let sum = 0;
for (const item of items) {
sum += item.qty * item.price;
}
return sum;
}
console.log(total([{ qty: 2, prise: 50 }]));
after.ts(11,30): error TS2561: Object literal may only specify known properties, but 'prise' does not exist in type 'Line'. Did you mean to write 'price'?
The same typo is now a compile error, at the line where you made it. Fix the spelling and it runs. The two any words became a type, Line[] and number.
Case 2: a callback
any or Function for a callback accepts anything, including a function that takes the wrong arguments. Write the signature.
type Line = { qty: number; price: number };
function keep(lines: Line[], test: (line: Line) => boolean): Line[] {
return lines.filter(test);
}
keep([{ qty: 1, price: 10 }], (line) => line.qty > 0);
keep([{ qty: 1, price: 10 }], (line) => line.qty);
callback.ts(8,41): error TS2322: Type 'number' is not assignable to type 'boolean'.
(line: Line) => boolean reads as "a function that takes a line and returns true or false". The second call returns a number, so it is refused. The first call needs no annotation on line, because the parameter type is inferred from keep.
Case 3: data from outside, like JSON
You do not know what is in it, and any would let you pretend. Use unknown and check what you need.
function describe(data: unknown): string {
if (typeof data === "object" && data !== null && "total" in data) {
if (typeof data.total === "number") {
return "Total: " + data.total.toFixed(2);
}
}
return "Unknown";
}
console.log(describe(JSON.parse('{"total": 12.5}')));
console.log(describe(JSON.parse('{"total": "x"}')));
Total: 12.50
Unknown
The checks are the price of not knowing. The second input has the wrong kind of total, and it falls through to "Unknown" instead of crashing.
⚠ Warning: Do not replace any with as SomeType. A cast says "trust me" and checks nothing. Use it only after a check you wrote yourself.
Case 4: you truly do not know yet
During a rename from JavaScript you will meet code you do not understand yet. Mark it so you can find it again, and keep going.
// TODO: type this properly. Shape comes from the old reporting module.
function legacy(report: unknown): void {
console.log(typeof report);
}
unknown is the honest placeholder. Anything that uses the value has to prove what it is first, so the compiler stays on your side while you decide.
Step 3: check the count
Search again. The number should be smaller, and every any left should be one you can explain in a sentence. Run npx tsc --noEmit after each change instead of at the end, so a new error points at the edit you just made.
Related course: TypeScript for Beginners.
About
Find every any, then replace each one with a named type, a function type or unknown with a check. After this, a typo like prise is a compile error instead of NaN.
- Responsible
- Christopher R
- Last Update
- 10/19/2026
- Reading Time
- 4 min
Reviews
Sign in to write a reviewComments (0)
Sign in to commentNo comments yet.