TypeScript Survival Guide

Favorite typescript videos

084 — Explicit Types (declare now, assign later: annotations, arrays, unions, objects)

Full companion narrative for TypeScript Tutorial #5 — explicit annotations for deferred values, typed arrays with the empty-array init rule, union types with the parentheses-before-brackets rule, and shaped object types

Video: 084 · TypeScript Tutorial #5 - Explicit Types · watch · ~8:35 · Net Ninja TypeScript tutorial series, lesson 5 (Shaun)

Source: this is a written companion to the video. Part of the Favorite TypeScript Videos curated path, module 00 (foundations). Inference needs a value to read from — this lesson covers what to do when the value comes later.

annotate up front when the value comes later

let character: string;
let age: number;
let isLoggedIn: boolean;

character = "luigi"; // fine
age = 30; // fine
isLoggedIn = true; // fine

sandbox.ts open with the lesson sections stubbed out

Lessons 3–4 inferred every type from an initializer. Here there is nothing to infer from yet, so the annotation carries the contract: “if I try to give it a value of a string, like Luigi, it’s not gonna let me do this, and we get an error.”

explicit string, number, and boolean declarations

The commented-out counterexamples stay in the file as documentation: age = 'luigi' and isLoggedIn = 25 would each fail the declared type.

matching assignments pass, mismatches stay commented out

typed arrays — and the empty-array init rule

let ninjas: string[] = ["shaun", "ryu", "chun-li"];
ninjas.push("ken"); // fine

ninjas array seeded and pushed

The element type goes before the brackets. Then the gotcha that earns its own browser trip: declaring let ninjas: string[] without initializing compiles cleanly, but the first push throws at runtime — “we get an error here. It says cannot read property push of undefined.” The fix is to initialize to [] whenever you plan to push.

uninitialized array and the push-of-undefined error

union types widen what is allowed

let mixed: (string | number | boolean)[] = [];
mixed.push("hello"); // fine
mixed.push(20); // fine
mixed.push(false); // fine — console shows (3) ["hello", 20, false]

mixed union array filling up

Parentheses before the brackets are required — (string | number | boolean)[]. “So I could come down here and say mixed.push, and it’s gonna be a string. hello, that would be fine.”

The same | works for scalars: let uid: string | number takes '123' or 123, but not false.

scalar uid union taking string then number

objects: from loose to shaped

let ninjaOne: { name: string; age: number } = { name: "yoshi", age: 30 };
let ninjaTwo: { name: string; age: number; beltColour: string };

ninjaOne shaped and ninjaTwo declared for later

A bare : object annotation is loose — it still admits arrays — while a shaped literal enforces required properties and rejects excess ones. “We’re just declaring the type it should be in the future.” First taste of structural typing; lesson 9 (type) and lesson 10 (signatures) build directly on it.

full file: unions, uid, and both ninja objects

Prev: 083 — Objects and Arrays · Next: 085 — Project Workflow with tsconfig

The auto-transcript mishears a few terms; this narrative uses the corrected forms: declaring a variable without initializing it (transcript “initializing a variable without giving it a value”), annotating the variable with a type (transcript “giving the variable a type”), initializing the array as an empty array, and union type for multi-type positions (transcript “one of two or one of three types”).