// selectedUserId can hold either a string or null
Note With strictNullChecks enabled (recommended), null and undefined are NOT assignable to other types unless you explicitly include them in a union. This catches a huge class of runtime bugs.
null typeundefined typenullablestrictNullChecksoptional value
any
syntax
let varName: any = value;
example
let legacyPayload: any = fetchFromOldApi();
legacyPayload.whatever.you.want; // No error
legacyPayload = 42;
legacyPayload = "now a string";
output
// Compiles without error — type checking is completely disabled
Note any disables ALL type safety for that value. It propagates silently — anything touching an any value also loses type info. Use unknown instead when you genuinely do not know the type.
any typedisable type checkingopt out typesuntyped variable
unknown
syntax
let varName: unknown = value;
example
let rawInput: unknown = JSON.parse(userInput);
// Must narrow before usingif (typeof rawInput === "string") {
console.log(rawInput.toUpperCase()); // OK
}
// rawInput.toUpperCase(); // Error: Object is of type 'unknown'
output
// Forces you to check the type before accessing properties
Note unknown is the type-safe counterpart to any. You can assign anything to unknown, but you cannot do anything with it until you narrow the type. Prefer unknown over any for incoming external data.
function throwAppError(msg: string): never {
thrownew Error(msg);
}
// Used for exhaustive checkstype Shape = "circle" | "square";
function getArea(shape: Shape): number {
switch (shape) {
case"circle": return Math.PI * 10;
case"square": return100;
default:
const _exhaustive: never = shape;
return _exhaustive;
}
}
output
// never means this code path should be unreachable
Note never represents values that never occur. A function returning never must not return normally (throw or infinite loop). Assigning to never in a default branch ensures you handle every union member — adding a new Shape member causes a compile error.
never typeexhaustive checkunreachable codethrow function type
// void indicates the function does not return a meaningful value
Note void is not the same as undefined. A void return type means the caller should not use the return value, but the function may technically return undefined. When used in callback types, void allows the implementation to return anything (the return is just ignored).
void typeno returnfunction returns nothingvoid vs undefined
symbol & bigint
syntax
let varName: symbol = Symbol(description);
let varName: bigint = valueBigInt;
example
const uniqueKey: unique symbol = Symbol("cacheKey");
let regularSym: symbol = Symbol("temp");
let hugeNumber: bigint = 9007199254740993n;
let anotherBig: bigint = BigInt("123456789012345678");
output
// unique symbol creates a distinct type; bigint handles arbitrarily large integers
Note unique symbol can only be used with const declarations and creates a specific subtype of symbol. bigint cannot be mixed with number in arithmetic — you must explicitly convert. bigint requires target ES2020 or later in tsconfig.
symbol typeunique symbolbigint typelarge numbersES2020 bigint
Arrays & Tuples
syntax
let arr: Type[] = [...];
let arr: Array<Type> = [...];
let tup: [TypeA, TypeB] = [a, b];
// userRecord[0] is string, userRecord[1] is number, userRecord[2] is boolean
Note Type[] and Array<Type> are identical. Tuples enforce length and per-position types at compile time, but at runtime they are just arrays — push() can still add elements unless you mark the tuple as readonly.
let varName: { key: Type; key2?: Type } = { ... };
let varName: object = { ... };
example
let product: { name: string; price: number; inStock?: boolean } = {
name: "Keyboard",
price: 79.99,
};
// The lowercase 'object' type means any non-primitivelet config: object = { debug: true };
// config.debug; // Error — object type has no known properties
output
// Use inline object types or interfaces for known shapes
Note Avoid the bare object type — it only means 'not a primitive' and has no property access. Use Record<string, unknown> for truly open-ended objects. The Object type (uppercase) matches nearly everything and is rarely useful.
object typetyped objectinline object typeobject vs Object