TypeScript's basic types are mostly JavaScript's own primitives with type annotations: string, number, boolean, plus arrays (string[]) and tuples (fixed-length, typed arrays). any opts a value out of type-checking entirely — TypeScript will not complain no matter how it's used, effectively reverting to plain JavaScript for that value. unknown is safer: it also accepts any value, but TypeScript refuses to let you use it for anything until you've narrowed its type with a runtime check.
Primitives, arrays, and tuples
A tuple's length and per-position types are both fixed — distinct from an array, whose elements are all the same type but can be any length.
let name: string = "Alice";
let age: number = 30;
let active: boolean = true;
let scores: number[] = [90, 85, 78]; // array: any length, all numbers
let point: [number, number] = [3, 4]; // tuple: exactly 2 numbers, fixed positionsany: opting out of type-checking
any is sometimes necessary (working with untyped legacy code, or a genuinely dynamic value), but it silently disables the type-checker's protection for anything it touches — a common source of bugs that TypeScript should have caught.
let data: any = fetchExternalData();
data.someProperty.deeplyNested.thatMayNotExist();
// no compile error at all — any means TypeScript checks NOTHING hereunknown: the type-safe alternative to any
unknown accepts any value just like any, but TypeScript refuses to let you call a method or access a property on it until you've proven its actual type with a runtime check — this is the type-safe default for genuinely unknown external data.
let data: unknown = fetchExternalData();
// data.someProperty; // COMPILE ERROR: object is of type 'unknown'
if (typeof data === "object" && data !== null && "someProperty" in data) {
console.log((data as { someProperty: string }).someProperty); // now safe
}