TypeScript any Type
last modified October 15, 2026
The any type turns off type checking for a value. A
variable of type any accepts every value, and the compiler allows
every operation on it: reading any property, calling it as a function,
assigning it to a variable of any other type. This makes any a
convenient escape hatch when migrating JavaScript code or working with data
of unknown shape, but it also means that the mistakes TypeScript is supposed
to catch go unnoticed until the program runs.
Basic Usage of any
A variable of type any can be assigned values of any
type.
let value: any = 42;
console.log(typeof value);
value = "Hello";
console.log(typeof value);
value = [1, 2, 3];
console.log(Array.isArray(value));
value = { foo: "bar" };
console.log(value);
The variable holds a number, a string, an array, and an object in
turn. With a specific type such as number, the second assignment
would already be an error. With any, the compiler keeps no
information about what the variable contains.
$ npx tsx basic_any.ts
number
string
true
{ foo: 'bar' }
any Hides Errors
Every operation on an any value compiles, whether or
not it makes sense.
function processInput(input: any): any {
return input.toUpperCase();
}
console.log(processInput("test"));
try {
console.log(processInput(5));
} catch (e) {
console.log(e instanceof Error ? e.message : e);
}
The function assumes that its input is a string. TypeScript cannot
check this assumption, so passing a number compiles and fails only at
runtime with a TypeError. With the parameter typed as
string, the second call would be rejected by the compiler.
$ npx tsx any_function.ts TEST input.toUpperCase is not a function
any with Objects
Properties of an any object can be read, written, and
called freely.
const data: any = { name: "Alice" };
data.age = 30;
data.active = true;
console.log(data);
console.log(data.nmae);
try {
data.save();
} catch (e) {
console.log(e instanceof Error ? e.message : e);
}
Adding properties works as in plain JavaScript. The misspelled
data.nmae compiles and quietly evaluates to
undefined, and the call to the missing save method
compiles and throws at runtime. Neither problem would get past the compiler
with a proper type for data.
$ npx tsx any_object.ts
{ name: 'Alice', age: 30, active: true }
undefined
data.save is not a function
any with Arrays
An any[] array accepts elements of any type.
const mixed: any[] = [1, "two"];
mixed.push(true);
mixed.push({ key: "value" });
console.log(mixed);
console.log(mixed.map(item => item.length));
The callback parameter item is also any,
so reading length compiles for every element, although only the
string has one. If the array really can contain different types, a union such
as (string | number | boolean)[] keeps the checks in
place.
$ npx tsx any_array.ts
[ 1, 'two', true, { key: 'value' } ]
[ undefined, 3, undefined, undefined ]
any Spreads
Values derived from an any value are usually
any as well. One untyped value can disable checking in a large
part of a program.
const config: any = { retries: "3", timeout: 500 };
const retries = config.retries + 1;
const timeout = config.timeout * 2;
const label: string = config.timeout;
console.log(retries, typeof retries);
console.log(timeout, label, typeof label);
Because config is any, so are
retries and timeout. The value of
retries is 31, a string, because "3" + 1
concatenates. The label variable is declared as
string, yet it holds a number: an any value can be
assigned to every type without any check.
$ npx tsx any_contagion.ts 31 string 1000 500 number
Implicit any
When TypeScript cannot infer the type of a parameter, it falls back
to any. The noImplicitAny option, which is part of
strict, reports such places.
function logValue(value) {
console.log(value);
}
function sum(values) {
return values.reduce((a, b) => a + b, 0);
}
Without the option, both functions compile and their parameters are
silently any. With it, the compiler asks for annotations such as
value: unknown or values: number[]. This is one of
the most important checks of strict mode.
$ npx tsc --noEmit implicit_any.ts(1,19): error TS7006: Parameter 'value' implicitly has an 'any' type. implicit_any.ts(5,14): error TS7006: Parameter 'values' implicitly has an 'any' type. implicit_any.ts(6,27): error TS7006: Parameter 'a' implicitly has an 'any' type. implicit_any.ts(6,30): error TS7006: Parameter 'b' implicitly has an 'any' type.
any with Type Assertions
A type assertion can turn an any value into a specific
type.
const rawData: any = "Hello World"; const str = rawData as string; console.log(str.toUpperCase()); const wrong = rawData as number; console.log(typeof wrong);
After the assertion, str has the string
type and the compiler checks its use again. The second assertion shows the
risk: it compiles, but the value is still a string. An assertion is a
promise to the compiler, not a conversion or a check.
$ npx tsx any_assertion.ts HELLO WORLD string
any in Untyped Libraries
JavaScript libraries without type definitions are imported with the
any type. Their results should be given a type as soon as
possible.
// imagine this function comes from a JavaScript library without types
const legacyApi: any = {
fetchUser: (id: number) => ({ id, name: "Alice", roles: ["admin"] }),
};
interface User {
id: number;
name: string;
roles: string[];
}
function getUser(id: number): User {
return legacyApi.fetchUser(id);
}
const user = getUser(1);
console.log(user.name, user.roles.join(", "));
The getUser wrapper is the only place that deals with
any. It declares the expected return type, so the rest of the
program works with a typed User. The type is still an
assumption; for data that may be malformed, it should be validated, as shown
in the unknown type tutorial. Many
libraries also have community types in the @types packages.
$ npx tsx any_library.ts Alice admin
any with JSON
JSON.parse returns any, because the
structure of the data is known only at runtime.
const jsonString = '{"id": 1, "title": "Book", "tags": ["new"]}';
const parsed = JSON.parse(jsonString);
console.log(parsed.title);
console.log(parsed.author);
console.log(parsed.tags.length);
interface Book {
id: number;
title: string;
tags: string[];
}
const book: Book = JSON.parse(jsonString);
console.log(book.title.toUpperCase());
The type of parsed is any, so the
non-existent author property compiles and is
undefined. Annotating the result as Book restores
type checking for the rest of the code, but nothing verifies that the JSON
really has this shape.
$ npx tsx any_json.ts Book undefined 1 BOOK
any versus unknown
The unknown type also accepts every value, but it
allows no operations until the value has been checked.
const a: any = 123;
try {
a.foo();
} catch (e) {
console.log(e instanceof Error ? e.message : e);
}
const u: unknown = 123;
if (typeof u === "number") {
console.log(u.toFixed(2));
}
Calling a.foo() compiles and fails at runtime. The
same call on u would not compile; the value must first be
narrowed, here with typeof, and then it can be used safely.
$ npx tsx any_vs_unknown.ts a.foo is not a function 123.00
const u: unknown = 123; u.foo(); const n: number = u;
These are the errors that any would have hidden. For
values whose type is not known, unknown is almost always the
better choice.
$ npx tsc --noEmit unknown_error.ts(3,1): error TS18046: 'u' is of type 'unknown'. unknown_error.ts(4,7): error TS2322: Type 'unknown' is not assignable to type 'number'.
Best Practices
- Enable Strict Mode:
noImplicitAnymakes everyanyexplicit and visible. - Prefer unknown: Use
unknownfor values of unknown type and narrow them before use. - Keep any Local: Confine
anyto a small wrapper and give its result a proper type. - Type JSON and Library Data: Annotate or validate the results of
JSON.parseand untyped libraries. - Lint for any: The
no-explicit-anyrule of typescript-eslint flags new uses ofany.
Source
This tutorial covered the any type. It is an escape
hatch from the type system; use it rarely, keep it local, and prefer
unknown for values whose type is not known.
Author
List all TypeScript tutorials.