Chapter 2 of 13
~12 minBasic Types
TypeScript's basic types cover the same primitives JavaScript already has - strings, numbers, booleans - plus a handful of TypeScript-specific types like `unknown`, `never`, and tuples that describe situations plain JavaScript has no vocabulary for.
Primitives: string, number, boolean
These map directly to their JavaScript counterparts. `number` covers both integers and floats (TypeScript, like JavaScript, has no separate integer type), `string` covers text, and `boolean` covers `true`/`false`. Annotating a variable with one of these restricts it to only ever holding that kind of value for the rest of its lifetime.
Try it yourself
let username: string = 'ada'; let age: number = 37; let isActive: boolean = true; // age = 'thirty-seven'; // Error: string is not assignable to number
No output yet. Use console.log() to print values here.
Arrays and Tuples
An array type is written either as `number[]` or the equivalent generic form `Array<number>` - both describe an array where every element is a number. A tuple, written `[string, number]`, is a fixed-length array where each position has its own specific type, which is useful for things like coordinate pairs or a `[key, value]` entry where the two slots mean different things.
The key difference from a regular array is that tuples enforce both length and per-position type at compile time - reading past the declared length, or assigning the wrong type at a given index, is an error.
Try it yourself
const scores: number[] = [85, 92, 78]; const names: Array<string> = ['Ada', 'Grace']; let point: [number, number] = [10, 20]; // point = [10, 20, 30]; // Error: source has 3 elements, target allows only 2 let entry: [string, number] = ['age', 37]; // entry = [37, 'age']; // Error: types are in the wrong order
No output yet. Use console.log() to print values here.
any, unknown, void, and never
`any` opts a value out of type checking entirely - it is assignable to and from anything, which defeats most of the benefit of using TypeScript at all, so it should be a deliberate, rare escape hatch rather than a default. `unknown` is the type-safe alternative: it can also hold any value, but the compiler will not let you call methods on it or pass it somewhere specific until you first narrow it to a more precise type.
`void` describes a function that does not return a meaningful value (its return is typically `undefined`), and is used almost exclusively as a return-type annotation. `never` describes a value that can never occur at all - a function that always throws, or always loops forever, has a return type of `never`, since it genuinely never produces a value to return to its caller.
Try it yourself
let notSure: unknown = 4; notSure = 'now a string'; // notSure.toUpperCase(); // Error: 'notSure' is of type 'unknown' if (typeof notSure === 'string') { notSure.toUpperCase(); // OK - narrowed to string inside this block } function logMessage(message: string): void { console.log(message); } function fail(message: string): never { throw new Error(message); }
No output yet. Use console.log() to print values here.
Type Inference
TypeScript infers a type from a variable's initializer whenever one is present, so `let count = 0` is inferred as `number` without needing an explicit annotation. This "best common type" inference also applies to arrays and function return values - a function that returns either a `string` or `number` on different code paths is inferred to return `string | number`, without you having to write that union out by hand.
Coding challenge
Declare a tuple [string, number, boolean] representing a product name, price, and in-stock flag. Then write a function describeProduct that accepts an unknown value, narrows it to check it is a string before using it, and returns a description.
// Write your solution here
No output yet. Use console.log() to print values here.
Answer every question below to mark this chapter as complete.
Quiz Yourself
Score: 0/51. What is the key practical difference between `any` and `unknown`?
2. What does a return type of `never` signal about a function?
3. How does a tuple type like `[string, number]` differ from an array type like `(string | number)[]`?
4. Given `let count = 0;` with no type annotation, what type does TypeScript infer for `count`?
5. Why is relying heavily on `any` throughout a codebase generally discouraged?