Skip to Content
Stop Using any: Replace It in 10 Minutes
Beginner
0 likes
Tutorials

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
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.